summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2011-11-25 19:42:34 +0000
committerRobin Watts <robin.watts@artifex.com>2011-11-25 19:42:34 +0000
commitbdf5c8848a2de071c8380fab86a1a49215ed5ee7 (patch)
tree8ff2e40bca4f337e5db112284992e6be67cea820 /draw
parent5f6c8d94faecc0bd87113a138befe554ab2172b2 (diff)
parent6e14149d3e915f559f99276a525862e28d6f0478 (diff)
downloadmupdf-bdf5c8848a2de071c8380fab86a1a49215ed5ee7.tar.xz
Merge branch 'master' into context
Diffstat (limited to 'draw')
-rw-r--r--draw/draw_device.c124
1 files changed, 61 insertions, 63 deletions
diff --git a/draw/draw_device.c b/draw/draw_device.c
index 5407d618..7e40ef3f 100644
--- a/draw/draw_device.c
+++ b/draw/draw_device.c
@@ -34,6 +34,21 @@ enum {
FZ_DRAWDEV_FLAGS_TYPE3 = 1,
};
+typedef struct fz_draw_stack_s fz_draw_stack;
+
+struct fz_draw_stack_s {
+ fz_bbox scissor;
+ fz_pixmap *dest;
+ fz_pixmap *mask;
+ fz_pixmap *shape;
+ int blendmode;
+ int luminosity;
+ float alpha;
+ fz_matrix ctm;
+ float xstep, ystep;
+ fz_rect area;
+};
+
struct fz_draw_device_s
{
fz_glyph_cache *cache;
@@ -47,18 +62,9 @@ struct fz_draw_device_s
int flags;
int top;
int blendmode;
- struct {
- fz_bbox scissor;
- fz_pixmap *dest;
- fz_pixmap *mask;
- fz_pixmap *shape;
- int blendmode;
- int luminosity;
- float alpha;
- fz_matrix ctm;
- float xstep, ystep;
- fz_rect area;
- } stack[STACK_SIZE];
+ fz_draw_stack *stack;
+ int stack_max;
+ fz_draw_stack init_stack[STACK_SIZE];
};
#ifdef DUMP_GROUP_BLENDS
@@ -89,6 +95,24 @@ static void dump_spaces(int x, const char *s)
#endif
+static void fz_grow_stack(fz_draw_device *dev)
+{
+ int max = dev->stack_max * 2;
+ fz_draw_stack *stack;
+
+ if (dev->stack == &dev->init_stack[0])
+ {
+ stack = fz_malloc(dev->ctx, sizeof(*stack) * max);
+ memcpy(stack, dev->stack, sizeof(*stack) * dev->stack_max);
+ }
+ else
+ {
+ stack = fz_resize_array(dev->ctx, dev->stack, max, sizeof(*stack));
+ }
+ dev->stack = stack;
+ dev->stack_max = max;
+}
+
static void fz_knockout_begin(fz_draw_device *dev)
{
fz_bbox bbox;
@@ -98,11 +122,8 @@ static void fz_knockout_begin(fz_draw_device *dev)
if ((dev->blendmode & FZ_BLEND_KNOCKOUT) == 0)
return;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
bbox = fz_bound_pixmap(dev->dest);
bbox = fz_intersect_bbox(bbox, dev->scissor);
@@ -158,11 +179,8 @@ static void fz_knockout_end(fz_draw_device *dev)
if ((dev->blendmode & FZ_BLEND_KNOCKOUT) == 0)
return;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
if (dev->top > 0)
{
@@ -323,11 +341,8 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, fz_rect *rect, int even_odd, f
fz_pixmap *mask, *dest, *shape;
fz_bbox bbox;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
fz_reset_gel(dev->gel, dev->scissor);
fz_flatten_fill_path(dev->gel, path, ctm, flatness);
@@ -394,11 +409,8 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, fz_rect *rect, fz_strok
fz_pixmap *mask, *dest, *shape;
fz_bbox bbox;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
if (linewidth * expansion < 0.1f)
linewidth = 1 / expansion;
@@ -607,11 +619,8 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate)
/* 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->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
if (accumulate == 0)
{
@@ -700,11 +709,8 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke
fz_pixmap *glyph;
int i, x, y, gid;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
/* make the mask the exact size needed */
bbox = fz_round_rect(fz_bound_text(text, ctm));
@@ -1041,11 +1047,8 @@ fz_draw_clip_image_mask(fz_device *devp, fz_pixmap *image, fz_rect *rect, fz_mat
fz_pixmap *scaled = NULL;
int dx, dy;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
#ifdef DUMP_GROUP_BLENDS
dump_spaces(dev->top, "Clip (image mask) begin\n");
@@ -1184,11 +1187,8 @@ fz_draw_begin_mask(fz_device *devp, fz_rect rect, int luminosity, fz_colorspace
fz_pixmap *shape = dev->shape;
fz_bbox bbox;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
bbox = fz_round_rect(rect);
bbox = fz_intersect_bbox(bbox, dev->scissor);
@@ -1246,11 +1246,8 @@ fz_draw_end_mask(fz_device *devp)
fz_bbox bbox;
int luminosity;
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
if (dev->top > 0)
{
@@ -1303,7 +1300,7 @@ fz_draw_begin_group(fz_device *devp, fz_rect rect, int isolated, int knockout, i
fz_bbox bbox;
fz_pixmap *dest, *shape;
- if (dev->top == STACK_SIZE)
+ if (dev->top == dev->stack_max)
{
fz_warn(dev->ctx, "assert: too many buffers on stack");
return;
@@ -1433,11 +1430,8 @@ fz_draw_begin_tile(fz_device *devp, fz_rect area, fz_rect view, float xstep, flo
/* area, view, xstep, ystep are in pattern space */
/* ctm maps from pattern space to device space */
- if (dev->top == STACK_SIZE)
- {
- fz_warn(dev->ctx, "assert: too many buffers on stack");
- return;
- }
+ if (dev->top == dev->stack_max)
+ fz_grow_stack(dev);
if (dev->blendmode & FZ_BLEND_KNOCKOUT)
fz_knockout_begin(dev);
@@ -1523,6 +1517,8 @@ fz_draw_free_user(fz_device *devp)
/* TODO: pop and free the stacks */
if (dev->top > 0)
fz_warn(dev->ctx, "items left on stack in draw device: %d", dev->top);
+ if (dev->stack != &dev->init_stack[0])
+ fz_free(dev->ctx, dev->stack);
fz_free_gel(dev->gel);
fz_free(devp->ctx, dev);
}
@@ -1540,6 +1536,8 @@ fz_new_draw_device(fz_context *ctx, fz_glyph_cache *cache, fz_pixmap *dest)
ddev->blendmode = 0;
ddev->flags = 0;
ddev->ctx = ctx;
+ ddev->stack = &ddev->init_stack[0];
+ ddev->stack_max = STACK_SIZE;
ddev->scissor.x0 = dest->x;
ddev->scissor.y0 = dest->y;