summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-02-24 13:02:18 +0100
committerTor Andersson <tor.andersson@artifex.com>2016-02-24 13:04:03 +0100
commita9043b470ba26fc5ec06e1d44ae8e9480d75724a (patch)
treeab0f875e720b3f9d74253d58eed5614ac5301756
parent35181e818efdc219a8fccf8479a73fa2b5db640f (diff)
downloadmupdf-a9043b470ba26fc5ec06e1d44ae8e9480d75724a.tar.xz
Add optional scissor hint argument to text clipping functions.
-rw-r--r--include/mupdf/fitz/device.h8
-rw-r--r--source/fitz/bbox-device.c4
-rw-r--r--source/fitz/device.c30
-rw-r--r--source/fitz/draw-device.c14
-rw-r--r--source/fitz/list-device.c16
-rw-r--r--source/fitz/stext-device.c4
-rw-r--r--source/fitz/svg-device.c4
-rw-r--r--source/fitz/trace-device.c4
-rw-r--r--source/pdf/pdf-device.c4
-rw-r--r--source/pdf/pdf-op-run.c10
-rw-r--r--source/xps/xps-glyphs.c2
11 files changed, 62 insertions, 38 deletions
diff --git a/include/mupdf/fitz/device.h b/include/mupdf/fitz/device.h
index d1f655ae..0e6b55f1 100644
--- a/include/mupdf/fitz/device.h
+++ b/include/mupdf/fitz/device.h
@@ -113,8 +113,8 @@ struct fz_device_s
void (*fill_text)(fz_context *, fz_device *, const fz_text *, const fz_matrix *, fz_colorspace *, const float *color, float alpha);
void (*stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, const fz_matrix *, fz_colorspace *, const float *color, float alpha);
- void (*clip_text)(fz_context *, fz_device *, const fz_text *, const fz_matrix *);
- void (*clip_stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, const fz_matrix *);
+ void (*clip_text)(fz_context *, fz_device *, const fz_text *, const fz_matrix *, const fz_rect *scissor);
+ void (*clip_stroke_text)(fz_context *, fz_device *, const fz_text *, const fz_stroke_state *, const fz_matrix *, const fz_rect *scissor);
void (*ignore_text)(fz_context *, fz_device *, const fz_text *, const fz_matrix *);
void (*fill_shade)(fz_context *, fz_device *, fz_shade *shd, const fz_matrix *ctm, float alpha);
@@ -152,8 +152,8 @@ void fz_clip_path(fz_context *ctx, fz_device *dev, const fz_path *path, int even
void fz_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor);
void fz_fill_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha);
void fz_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha);
-void fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm);
-void fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm);
+void fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor);
+void fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor);
void fz_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm);
void fz_pop_clip(fz_context *ctx, fz_device *dev);
void fz_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_matrix *ctm, float alpha);
diff --git a/source/fitz/bbox-device.c b/source/fitz/bbox-device.c
index 4fd8e7f9..247fdb30 100644
--- a/source/fitz/bbox-device.c
+++ b/source/fitz/bbox-device.c
@@ -102,14 +102,14 @@ fz_bbox_clip_stroke_path(fz_context *ctx, fz_device *dev, const fz_path *path, c
}
static void
-fz_bbox_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm)
+fz_bbox_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_rect r;
fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, NULL, ctm, &r), 1);
}
static void
-fz_bbox_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+fz_bbox_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_rect r;
fz_bbox_add_rect(ctx, dev, fz_bound_text(ctx, text, stroke, ctm, &r), 1);
diff --git a/source/fitz/device.c b/source/fitz/device.c
index d9dffc5d..fdee2042 100644
--- a/source/fitz/device.c
+++ b/source/fitz/device.c
@@ -180,7 +180,7 @@ fz_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_st
}
void
-fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm)
+fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
if (dev->error_depth)
{
@@ -192,12 +192,17 @@ fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matr
{
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
{
- fz_rect bbox;
- fz_bound_text(ctx, text, NULL, ctm, &bbox);
- push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_text);
+ if (scissor == NULL)
+ {
+ fz_rect bbox;
+ fz_bound_text(ctx, text, NULL, ctm, &bbox);
+ push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_text);
+ }
+ else
+ push_clip_stack(ctx, dev, scissor, fz_device_container_stack_is_clip_text);
}
if (dev->clip_text)
- dev->clip_text(ctx, dev, text, ctm);
+ dev->clip_text(ctx, dev, text, ctm, scissor);
}
fz_catch(ctx)
{
@@ -208,7 +213,7 @@ fz_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matr
}
void
-fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
if (dev->error_depth)
{
@@ -220,12 +225,17 @@ fz_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const
{
if (dev->hints & FZ_MAINTAIN_CONTAINER_STACK)
{
- fz_rect bbox;
- fz_bound_text(ctx, text, stroke, ctm, &bbox);
- push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_stroke_text);
+ if (scissor == NULL)
+ {
+ fz_rect bbox;
+ fz_bound_text(ctx, text, stroke, ctm, &bbox);
+ push_clip_stack(ctx, dev, &bbox, fz_device_container_stack_is_clip_stroke_text);
+ }
+ else
+ push_clip_stack(ctx, dev, scissor, fz_device_container_stack_is_clip_stroke_text);
}
if (dev->clip_stroke_text)
- dev->clip_stroke_text(ctx, dev, text, stroke, ctm);
+ dev->clip_stroke_text(ctx, dev, text, stroke, ctm, scissor);
}
fz_catch(ctx)
{
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c
index 978e81cc..83195cd1 100644
--- a/source/fitz/draw-device.c
+++ b/source/fitz/draw-device.c
@@ -708,7 +708,7 @@ fz_draw_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const
}
static void
-fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_matrix *ctm)
+fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_draw_device *dev = (fz_draw_device*)devp;
fz_irect bbox;
@@ -728,6 +728,11 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f
/* make the mask the exact size needed */
fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, NULL, ctm, &rect));
fz_intersect_irect(&bbox, &state->scissor);
+ if (scissor)
+ {
+ fz_irect bbox2;
+ fz_intersect_irect(&bbox, fz_irect_from_rect(&bbox2, scissor));
+ }
fz_try(ctx)
{
@@ -821,7 +826,7 @@ fz_draw_clip_text(fz_context *ctx, fz_device *devp, const fz_text *text, const f
}
static void
-fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_draw_device *dev = (fz_draw_device*)devp;
fz_irect bbox;
@@ -838,6 +843,11 @@ fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, const fz_text *text,
/* make the mask the exact size needed */
fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, stroke, ctm, &rect));
fz_intersect_irect(&bbox, &state->scissor);
+ if (scissor)
+ {
+ fz_irect bbox2;
+ fz_intersect_irect(&bbox, fz_irect_from_rect(&bbox2, scissor));
+ }
fz_try(ctx)
{
diff --git a/source/fitz/list-device.c b/source/fitz/list-device.c
index 42485766..1d416073 100644
--- a/source/fitz/list-device.c
+++ b/source/fitz/list-device.c
@@ -186,6 +186,8 @@ fz_append_display_node(
{
case FZ_CMD_CLIP_PATH:
case FZ_CMD_CLIP_STROKE_PATH:
+ case FZ_CMD_CLIP_TEXT:
+ case FZ_CMD_CLIP_STROKE_TEXT:
case FZ_CMD_CLIP_IMAGE_MASK:
if (writer->top < STACK_SIZE)
{
@@ -195,8 +197,6 @@ fz_append_display_node(
writer->top++;
break;
case FZ_CMD_END_MASK:
- case FZ_CMD_CLIP_TEXT:
- case FZ_CMD_CLIP_STROKE_TEXT:
if (writer->top < STACK_SIZE)
{
writer->stack[writer->top].update = NULL;
@@ -836,7 +836,7 @@ fz_list_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const
}
static void
-fz_list_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm)
+fz_list_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_rect rect;
fz_text *cloned_text = fz_keep_text(ctx, text);
@@ -844,6 +844,8 @@ fz_list_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz
fz_try(ctx)
{
fz_bound_text(ctx, text, NULL, ctm, &rect);
+ if (scissor)
+ fz_intersect_rect(&rect, scissor);
fz_append_display_node(
ctx,
dev,
@@ -867,7 +869,7 @@ fz_list_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz
}
static void
-fz_list_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+fz_list_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_rect rect;
fz_text *cloned_text = fz_keep_text(ctx, text);
@@ -875,6 +877,8 @@ fz_list_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, c
fz_try(ctx)
{
fz_bound_text(ctx, text, stroke, ctm, &rect);
+ if (scissor)
+ fz_intersect_rect(&rect, scissor);
fz_append_display_node(
ctx,
dev,
@@ -1683,10 +1687,10 @@ visible:
fz_stroke_text(ctx, dev, *(fz_text **)node, stroke, &trans_ctm, colorspace, color, alpha);
break;
case FZ_CMD_CLIP_TEXT:
- fz_clip_text(ctx, dev, *(fz_text **)node, &trans_ctm);
+ fz_clip_text(ctx, dev, *(fz_text **)node, &trans_ctm, &trans_rect);
break;
case FZ_CMD_CLIP_STROKE_TEXT:
- fz_clip_stroke_text(ctx, dev, *(fz_text **)node, stroke, &trans_ctm);
+ fz_clip_stroke_text(ctx, dev, *(fz_text **)node, stroke, &trans_ctm, &trans_rect);
break;
case FZ_CMD_IGNORE_TEXT:
fz_ignore_text(ctx, dev, *(fz_text **)node, &trans_ctm);
diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c
index 9652436a..1decf5af 100644
--- a/source/fitz/stext-device.c
+++ b/source/fitz/stext-device.c
@@ -854,7 +854,7 @@ fz_stext_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const
}
static void
-fz_stext_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm)
+fz_stext_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_stext_device *tdev = (fz_stext_device*)dev;
fz_stext_style *style;
@@ -867,7 +867,7 @@ fz_stext_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const f
}
static void
-fz_stext_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+fz_stext_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_stext_device *tdev = (fz_stext_device*)dev;
fz_stext_style *style;
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index 3295bf7e..e57b8f5a 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -602,7 +602,7 @@ svg_dev_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const
}
static void
-svg_dev_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm)
+svg_dev_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
svg_device *sdev = (svg_device*)dev;
fz_output *out = sdev->out;
@@ -632,7 +632,7 @@ svg_dev_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz
}
static void
-svg_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+svg_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
svg_device *sdev = (svg_device*)dev;
diff --git a/source/fitz/trace-device.c b/source/fitz/trace-device.c
index 4d1e5b9b..fd9adcb5 100644
--- a/source/fitz/trace-device.c
+++ b/source/fitz/trace-device.c
@@ -215,7 +215,7 @@ fz_trace_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const
}
static void
-fz_trace_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm)
+fz_trace_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_output *out = ((fz_trace_device*)dev)->out;
fz_printf(ctx, out, "<clip_text");
@@ -226,7 +226,7 @@ fz_trace_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const f
}
static void
-fz_trace_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+fz_trace_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
fz_output *out = ((fz_trace_device*)dev)->out;
fz_printf(ctx, out, "<clip_stroke_text");
diff --git a/source/pdf/pdf-device.c b/source/pdf/pdf-device.c
index d141c476..85e2f27d 100644
--- a/source/pdf/pdf-device.c
+++ b/source/pdf/pdf-device.c
@@ -983,7 +983,7 @@ pdf_dev_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const
}
static void
-pdf_dev_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm)
+pdf_dev_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm, const fz_rect *scissor)
{
pdf_device *pdev = (pdf_device*)dev;
fz_text_span *span;
@@ -1002,7 +1002,7 @@ pdf_dev_clip_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz
}
static void
-pdf_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm)
+pdf_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_stroke_state *stroke, const fz_matrix *ctm, const fz_rect *scissor)
{
pdf_device *pdev = (pdf_device*)dev;
fz_text_span *span;
diff --git a/source/pdf/pdf-op-run.c b/source/pdf/pdf-op-run.c
index 8d974dcf..0bd72b63 100644
--- a/source/pdf/pdf-op-run.c
+++ b/source/pdf/pdf-op-run.c
@@ -793,7 +793,7 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
case PDF_MAT_PATTERN:
if (gstate->fill.pattern)
{
- fz_clip_text(ctx, pr->dev, text, &gstate->ctm);
+ fz_clip_text(ctx, pr->dev, text, &gstate->ctm, &tb);
pdf_show_pattern(ctx, pr, gstate->fill.pattern, &pr->gstate[gstate->fill.gstate_num], &tb, PDF_FILL);
fz_pop_clip(ctx, pr->dev);
}
@@ -801,7 +801,7 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
case PDF_MAT_SHADE:
if (gstate->fill.shade)
{
- fz_clip_text(ctx, pr->dev, text, &gstate->ctm);
+ fz_clip_text(ctx, pr->dev, text, &gstate->ctm, &tb);
/* Page 2 of patterns.pdf shows that fz_fill_shade should NOT be called with gstate->ctm */
fz_fill_shade(ctx, pr->dev, gstate->fill.shade, &pr->gstate[gstate->fill.gstate_num].ctm, gstate->fill.alpha);
fz_pop_clip(ctx, pr->dev);
@@ -823,7 +823,7 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
case PDF_MAT_PATTERN:
if (gstate->stroke.pattern)
{
- fz_clip_stroke_text(ctx, pr->dev, text, gstate->stroke_state, &gstate->ctm);
+ fz_clip_stroke_text(ctx, pr->dev, text, gstate->stroke_state, &gstate->ctm, &tb);
pdf_show_pattern(ctx, pr, gstate->stroke.pattern, &pr->gstate[gstate->stroke.gstate_num], &tb, PDF_STROKE);
fz_pop_clip(ctx, pr->dev);
}
@@ -831,7 +831,7 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
case PDF_MAT_SHADE:
if (gstate->stroke.shade)
{
- fz_clip_stroke_text(ctx, pr->dev, text, gstate->stroke_state, &gstate->ctm);
+ fz_clip_stroke_text(ctx, pr->dev, text, gstate->stroke_state, &gstate->ctm, &tb);
fz_fill_shade(ctx, pr->dev, gstate->stroke.shade, &pr->gstate[gstate->stroke.gstate_num].ctm, gstate->stroke.alpha);
fz_pop_clip(ctx, pr->dev);
}
@@ -848,7 +848,7 @@ pdf_flush_text(fz_context *ctx, pdf_run_processor *pr)
if (doclip)
{
gstate->clip_depth++;
- fz_clip_text(ctx, pr->dev, text, &gstate->ctm);
+ fz_clip_text(ctx, pr->dev, text, &gstate->ctm, &tb);
}
}
fz_always(ctx)
diff --git a/source/xps/xps-glyphs.c b/source/xps/xps-glyphs.c
index 5d343428..689209cd 100644
--- a/source/xps/xps-glyphs.c
+++ b/source/xps/xps-glyphs.c
@@ -614,7 +614,7 @@ xps_parse_glyphs(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
if (fill_tag)
{
- fz_clip_text(ctx, dev, text, &local_ctm);
+ fz_clip_text(ctx, dev, text, &local_ctm, &area);
xps_parse_brush(ctx, doc, &local_ctm, &area, fill_uri, dict, fill_tag);
fz_pop_clip(ctx, dev);
}