summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
Diffstat (limited to 'fitz')
-rw-r--r--fitz/base_geometry.c30
-rw-r--r--fitz/dev_list.c87
-rw-r--r--fitz/dev_null.c12
-rw-r--r--fitz/dev_trace.c6
-rw-r--r--fitz/fitz.h14
-rw-r--r--fitz/res_path.c2
6 files changed, 128 insertions, 23 deletions
diff --git a/fitz/base_geometry.c b/fitz/base_geometry.c
index 302ef966..00a85c9b 100644
--- a/fitz/base_geometry.c
+++ b/fitz/base_geometry.c
@@ -160,6 +160,36 @@ fz_round_rect(fz_rect f)
return i;
}
+fz_rect
+fz_intersect_rect(fz_rect a, fz_rect b)
+{
+ fz_rect r;
+ if (fz_is_infinite_rect(a)) return b;
+ if (fz_is_infinite_rect(b)) return a;
+ if (fz_is_empty_rect(a)) return fz_empty_rect;
+ if (fz_is_empty_rect(b)) return fz_empty_rect;
+ r.x0 = MAX(a.x0, b.x0);
+ r.y0 = MAX(a.y0, b.y0);
+ r.x1 = MIN(a.x1, b.x1);
+ r.y1 = MIN(a.y1, b.y1);
+ return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_rect : r;
+}
+
+fz_rect
+fz_union_rect(fz_rect a, fz_rect b)
+{
+ fz_rect r;
+ if (fz_is_infinite_rect(a)) return a;
+ if (fz_is_infinite_rect(b)) return b;
+ if (fz_is_empty_rect(a)) return b;
+ if (fz_is_empty_rect(b)) return a;
+ r.x0 = MIN(a.x0, b.x0);
+ r.y0 = MIN(a.y0, b.y0);
+ r.x1 = MAX(a.x1, b.x1);
+ r.y1 = MAX(a.y1, b.y1);
+ return r;
+}
+
fz_bbox
fz_intersect_bbox(fz_bbox a, fz_bbox b)
{
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
index eeb4e485..44528d8b 100644
--- a/fitz/dev_list.c
+++ b/fitz/dev_list.c
@@ -2,6 +2,8 @@
typedef struct fz_display_node_s fz_display_node;
+#define STACK_SIZE 96
+
typedef enum fz_display_command_e
{
FZ_CMD_FILL_PATH,
@@ -50,6 +52,13 @@ struct fz_display_list_s
{
fz_display_node *first;
fz_display_node *last;
+
+ int top;
+ struct {
+ fz_rect *update;
+ fz_rect rect;
+ } stack[STACK_SIZE];
+ int tiled;
};
enum { ISOLATED = 1, KNOCKOUT = 2 };
@@ -98,6 +107,54 @@ fz_clone_stroke_state(fz_stroke_state *stroke)
static void
fz_append_display_node(fz_display_list *list, fz_display_node *node)
{
+ switch (node->cmd) {
+ case FZ_CMD_CLIP_PATH:
+ case FZ_CMD_CLIP_STROKE_PATH:
+ case FZ_CMD_CLIP_IMAGE_MASK:
+ list->stack[list->top].update = &node->rect;
+ list->stack[list->top].rect = fz_empty_rect;
+ list->top++;
+ break;
+ case FZ_CMD_CLIP_TEXT:
+ case FZ_CMD_CLIP_STROKE_TEXT:
+ list->stack[list->top].update = NULL;
+ list->stack[list->top].rect = fz_empty_rect;
+ list->top++;
+ break;
+ case FZ_CMD_BEGIN_TILE:
+ list->tiled++;
+ if (list->top > 0) {
+ list->stack[list->top-1].rect = fz_infinite_rect;
+ }
+ break;
+ case FZ_CMD_END_TILE:
+ list->tiled--;
+ break;
+ case FZ_CMD_END_GROUP:
+ break;
+ case FZ_CMD_POP_CLIP:
+ if (list->top > 0) {
+ fz_rect *update;
+ list->top--;
+ update = list->stack[list->top].update;
+ if (list->tiled == 0) {
+ if (update != NULL) {
+ *update = fz_intersect_rect(*update, list->stack[list->top].rect);
+ node->rect = *update;
+ } else {
+ node->rect = list->stack[list->top].rect;
+ }
+ } else {
+ node->rect = fz_infinite_rect;
+ }
+ }
+ /*@fallthrough@*/
+ default:
+ if ((list->top > 0) && (list->tiled == 0)) {
+ list->stack[list->top-1].rect = fz_union_rect(list->stack[list->top-1].rect, node->rect);
+ }
+ break;
+ }
if (!list->first)
{
list->first = node;
@@ -177,22 +234,26 @@ fz_list_stroke_path(void *user, fz_path *path, fz_stroke_state *stroke, fz_matri
}
static void
-fz_list_clip_path(void *user, fz_path *path, int even_odd, fz_matrix ctm)
+fz_list_clip_path(void *user, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_PATH, ctm, NULL, NULL, 0);
node->rect = fz_bound_path(path, NULL, ctm);
+ if (rect != NULL)
+ node->rect = fz_intersect_rect(node->rect, *rect);
node->item.path = fz_clone_path(path);
node->flag = even_odd;
fz_append_display_node(user, node);
}
static void
-fz_list_clip_stroke_path(void *user, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm)
+fz_list_clip_stroke_path(void *user, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_STROKE_PATH, ctm, NULL, NULL, 0);
node->rect = fz_bound_path(path, stroke, ctm);
+ if (rect != NULL)
+ node->rect = fz_intersect_rect(node->rect, *rect);
node->item.path = fz_clone_path(path);
node->stroke = fz_clone_stroke_state(stroke);
fz_append_display_node(user, node);
@@ -261,7 +322,6 @@ fz_list_pop_clip(void *user)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_POP_CLIP, fz_identity, NULL, NULL, 0);
- /* TODO: scan back for matching pushclip and calculate bbox of contents */
fz_append_display_node(user, node);
}
@@ -297,11 +357,13 @@ fz_list_fill_image_mask(void *user, fz_pixmap *image, fz_matrix ctm,
}
static void
-fz_list_clip_image_mask(void *user, fz_pixmap *image, fz_matrix ctm)
+fz_list_clip_image_mask(void *user, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
{
fz_display_node *node;
node = fz_new_display_node(FZ_CMD_CLIP_IMAGE_MASK, ctm, NULL, NULL, 0);
node->rect = fz_transform_rect(ctm, fz_unit_rect);
+ if (rect != NULL)
+ node->rect = fz_intersect_rect(node->rect, *rect);
node->item.image = fz_keep_pixmap(image);
fz_append_display_node(user, node);
}
@@ -407,6 +469,8 @@ fz_new_display_list(void)
fz_display_list *list = fz_malloc(sizeof(fz_display_list));
list->first = NULL;
list->last = NULL;
+ list->top = 0;
+ list->tiled = 0;
return list;
}
@@ -499,11 +563,17 @@ visible:
node->colorspace, node->color, node->alpha);
break;
case FZ_CMD_CLIP_PATH:
- fz_clip_path(dev, node->item.path, node->flag, ctm);
+ {
+ fz_rect trect = fz_transform_rect(top_ctm, node->rect);
+ fz_clip_path(dev, node->item.path, &trect, node->flag, ctm);
break;
+ }
case FZ_CMD_CLIP_STROKE_PATH:
- fz_clip_stroke_path(dev, node->item.path, node->stroke, ctm);
+ {
+ fz_rect trect = fz_transform_rect(top_ctm, node->rect);
+ fz_clip_stroke_path(dev, node->item.path, &trect, node->stroke, ctm);
break;
+ }
case FZ_CMD_FILL_TEXT:
fz_fill_text(dev, node->item.text, ctm,
node->colorspace, node->color, node->alpha);
@@ -532,8 +602,11 @@ visible:
node->colorspace, node->color, node->alpha);
break;
case FZ_CMD_CLIP_IMAGE_MASK:
- fz_clip_image_mask(dev, node->item.image, ctm);
+ {
+ fz_rect trect = fz_transform_rect(top_ctm, node->rect);
+ fz_clip_image_mask(dev, node->item.image, &trect, ctm);
break;
+ }
case FZ_CMD_POP_CLIP:
fz_pop_clip(dev);
break;
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index f81b330c..4d40ef73 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -35,17 +35,17 @@ fz_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix
}
void
-fz_clip_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm)
+fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm)
{
if (dev->clip_path)
- dev->clip_path(dev->user, path, even_odd, ctm);
+ dev->clip_path(dev->user, path, rect, even_odd, ctm);
}
void
-fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm)
+fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm)
{
if (dev->clip_stroke_path)
- dev->clip_stroke_path(dev->user, path, stroke, ctm);
+ dev->clip_stroke_path(dev->user, path, rect, stroke, ctm);
}
void
@@ -115,10 +115,10 @@ fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm,
}
void
-fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm)
+fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
{
if (dev->clip_image_mask)
- dev->clip_image_mask(dev->user, image, ctm);
+ dev->clip_image_mask(dev->user, image, rect, ctm);
}
void
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
index 9e6853b8..06f749f9 100644
--- a/fitz/dev_trace.c
+++ b/fitz/dev_trace.c
@@ -105,7 +105,7 @@ fz_trace_stroke_path(void *user, fz_path *path, fz_stroke_state *stroke, fz_matr
}
static void
-fz_trace_clip_path(void *user, fz_path *path, int even_odd, fz_matrix ctm)
+fz_trace_clip_path(void *user, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm)
{
printf("<clip_path ");
if (even_odd)
@@ -119,7 +119,7 @@ fz_trace_clip_path(void *user, fz_path *path, int even_odd, fz_matrix ctm)
}
static void
-fz_trace_clip_stroke_path(void *user, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm)
+fz_trace_clip_stroke_path(void *user, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm)
{
printf("<clip_stroke_path ");
fz_trace_matrix(ctm);
@@ -210,7 +210,7 @@ fz_colorspace *colorspace, float *color, float alpha)
}
static void
-fz_trace_clip_image_mask(void *user, fz_pixmap *image, fz_matrix ctm)
+fz_trace_clip_image_mask(void *user, fz_pixmap *image, fz_rect *rect, fz_matrix ctm)
{
printf("<clip_image_mask ");
fz_trace_matrix(ctm);
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 381ae919..5bc22f4e 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -264,7 +264,9 @@ float fz_matrix_expansion(fz_matrix m);
fz_bbox fz_round_rect(fz_rect r);
fz_bbox fz_intersect_bbox(fz_bbox a, fz_bbox b);
+fz_rect fz_intersect_rect(fz_rect a, fz_rect b);
fz_bbox fz_union_bbox(fz_bbox a, fz_bbox b);
+fz_rect fz_union_rect(fz_rect a, fz_rect b);
fz_point fz_transform_point(fz_matrix m, fz_point p);
fz_point fz_transform_vector(fz_matrix m, fz_point p);
@@ -954,8 +956,8 @@ struct fz_device_s
void (*fill_path)(void *, fz_path *, int even_odd, fz_matrix, fz_colorspace *, float *color, float alpha);
void (*stroke_path)(void *, fz_path *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
- void (*clip_path)(void *, fz_path *, int even_odd, fz_matrix);
- void (*clip_stroke_path)(void *, fz_path *, fz_stroke_state *, fz_matrix);
+ void (*clip_path)(void *, fz_path *, fz_rect *rect, int even_odd, fz_matrix);
+ void (*clip_stroke_path)(void *, fz_path *, fz_rect *rect, fz_stroke_state *, fz_matrix);
void (*fill_text)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
void (*stroke_text)(void *, fz_text *, fz_stroke_state *, fz_matrix, fz_colorspace *, float *color, float alpha);
@@ -966,7 +968,7 @@ struct fz_device_s
void (*fill_shade)(void *, fz_shade *shd, fz_matrix ctm, float alpha);
void (*fill_image)(void *, fz_pixmap *img, fz_matrix ctm, float alpha);
void (*fill_image_mask)(void *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
- void (*clip_image_mask)(void *, fz_pixmap *img, fz_matrix ctm);
+ void (*clip_image_mask)(void *, fz_pixmap *img, fz_rect *rect, fz_matrix ctm);
void (*pop_clip)(void *);
@@ -981,8 +983,8 @@ struct fz_device_s
void fz_fill_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
void fz_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_clip_path(fz_device *dev, fz_path *path, int even_odd, fz_matrix ctm);
-void fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_stroke_state *stroke, fz_matrix ctm);
+void fz_clip_path(fz_device *dev, fz_path *path, fz_rect *rect, int even_odd, fz_matrix ctm);
+void fz_clip_stroke_path(fz_device *dev, fz_path *path, fz_rect *rect, fz_stroke_state *stroke, fz_matrix ctm);
void fz_fill_text(fz_device *dev, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
void fz_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
void fz_clip_text(fz_device *dev, fz_text *text, fz_matrix ctm, int accumulate);
@@ -992,7 +994,7 @@ void fz_pop_clip(fz_device *dev);
void fz_fill_shade(fz_device *dev, fz_shade *shade, fz_matrix ctm, float alpha);
void fz_fill_image(fz_device *dev, fz_pixmap *image, fz_matrix ctm, float alpha);
void fz_fill_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_matrix ctm);
+void fz_clip_image_mask(fz_device *dev, fz_pixmap *image, fz_rect *rect, fz_matrix ctm);
void fz_begin_mask(fz_device *dev, fz_rect area, int luminosity, fz_colorspace *colorspace, float *bc);
void fz_end_mask(fz_device *dev);
void fz_begin_group(fz_device *dev, fz_rect area, int isolated, int knockout, int blendmode, float alpha);
diff --git a/fitz/res_path.c b/fitz/res_path.c
index 4959754b..b9eb1ee3 100644
--- a/fitz/res_path.c
+++ b/fitz/res_path.c
@@ -158,7 +158,7 @@ fz_bound_path(fz_path *path, fz_stroke_state *stroke, fz_matrix ctm)
if (stroke)
{
- float miterlength = sinf(stroke->miterlimit * 0.5f);
+ float miterlength = stroke->miterlimit;
float linewidth = stroke->linewidth;
float expand = MAX(miterlength, linewidth) * 0.5f;
r.x0 -= expand;