diff options
Diffstat (limited to 'source/fitz/draw-device.c')
-rw-r--r-- | source/fitz/draw-device.c | 741 |
1 files changed, 354 insertions, 387 deletions
diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index 4592f8cf..fad44050 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -37,8 +37,8 @@ struct fz_draw_state_s { struct fz_draw_device_s { + fz_device super; fz_gel *gel; - fz_context *ctx; int flags; int top; fz_scale_cache *cache_x; @@ -77,11 +77,11 @@ static void dump_spaces(int x, const char *s) #endif #ifdef DUMP_STACK_CHANGES -#define STACK_PUSHED(A) stack_change(dev, ">" ## A) -#define STACK_POPPED(A) stack_change(dev, "<" ## A) -#define STACK_CONVERT(A) stack_change(dev, A) +#define STACK_PUSHED(A) stack_change(ctx, dev, ">" ## A) +#define STACK_POPPED(A) stack_change(ctx, dev, "<" ## A) +#define STACK_CONVERT(A) stack_change(ctx, dev, A) -static void stack_change(fz_draw_device *dev, char *s) +static void stack_change(fz_context *ctx, fz_draw_device *dev, char *s) { int depth = dev->top; int n; @@ -100,19 +100,19 @@ static void stack_change(fz_draw_device *dev, char *s) #endif -static void fz_grow_stack(fz_draw_device *dev) +static void fz_grow_stack(fz_context *ctx, fz_draw_device *dev) { int max = dev->stack_cap * 2; fz_draw_state *stack; if (dev->stack == &dev->init_stack[0]) { - stack = fz_malloc(dev->ctx, sizeof(*stack) * max); + stack = Memento_label(fz_malloc_array(ctx, max, sizeof *stack), "draw device stack"); memcpy(stack, dev->stack, sizeof(*stack) * dev->stack_cap); } else { - stack = fz_resize_array(dev->ctx, dev->stack, max, sizeof(*stack)); + stack = fz_resize_array(ctx, dev->stack, max, sizeof(*stack)); } dev->stack = stack; dev->stack_cap = max; @@ -122,22 +122,20 @@ static void fz_grow_stack(fz_draw_device *dev) * already having been initialised to contain the same thing. Simply * change any contents of state[1] that you want to and continue. */ static fz_draw_state * -push_stack(fz_draw_device *dev) +push_stack(fz_context *ctx, fz_draw_device *dev) { fz_draw_state *state; if (dev->top == dev->stack_cap-1) - fz_grow_stack(dev); + fz_grow_stack(ctx, dev); state = &dev->stack[dev->top]; dev->top++; memcpy(&state[1], state, sizeof(*state)); return state; } -static void emergency_pop_stack(fz_draw_device *dev, fz_draw_state *state) +static void emergency_pop_stack(fz_context *ctx, fz_draw_device *dev, fz_draw_state *state) { - fz_context *ctx = dev->ctx; - if (state[1].mask != state[0].mask) fz_drop_pixmap(ctx, state[1].mask); if (state[1].dest != state[0].dest) @@ -150,9 +148,8 @@ static void emergency_pop_stack(fz_draw_device *dev, fz_draw_state *state) } static fz_draw_state * -fz_knockout_begin(fz_draw_device *dev) +fz_knockout_begin(fz_context *ctx, fz_draw_device *dev) { - fz_context *ctx = dev->ctx; fz_irect bbox; fz_pixmap *dest, *shape; fz_draw_state *state = &dev->stack[dev->top]; @@ -161,12 +158,12 @@ fz_knockout_begin(fz_draw_device *dev) if ((state->blendmode & FZ_BLEND_KNOCKOUT) == 0) return state; - state = push_stack(dev); + state = push_stack(ctx, dev); STACK_PUSHED("knockout"); - fz_pixmap_bbox(dev->ctx, state->dest, &bbox); + fz_pixmap_bbox(ctx, state->dest, &bbox); fz_intersect_irect(&bbox, &state->scissor); - dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, &bbox); + dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox); if (isolated) { @@ -197,8 +194,8 @@ fz_knockout_begin(fz_draw_device *dev) } else { - shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, shape); + shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, shape); } #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top-1, "Knockout begin\n"); @@ -211,12 +208,11 @@ fz_knockout_begin(fz_draw_device *dev) return &state[1]; } -static void fz_knockout_end(fz_draw_device *dev) +static void fz_knockout_end(fz_context *ctx, fz_draw_device *dev) { fz_draw_state *state; int blendmode; int isolated; - fz_context *ctx = dev->ctx; if (dev->top == 0) { @@ -233,12 +229,12 @@ static void fz_knockout_end(fz_draw_device *dev) #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top, ""); - fz_dump_blend(dev->ctx, state[1].dest, "Knockout end: blending "); + fz_dump_blend(ctx, state[1].dest, "Knockout end: blending "); if (state[1].shape) - fz_dump_blend(dev->ctx, state[1].shape, "/"); - fz_dump_blend(dev->ctx, state[0].dest, " onto "); + fz_dump_blend(ctx, state[1].shape, "/"); + fz_dump_blend(ctx, state[0].dest, " onto "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[0].shape, "/"); if (blendmode != 0) printf(" (blend %d)", blendmode); if (isolated != 0) @@ -254,26 +250,28 @@ static void fz_knockout_end(fz_draw_device *dev) * errors can cause the stack to get out of sync, and this saves our * bacon. */ if (state[0].dest != state[1].dest) - fz_drop_pixmap(dev->ctx, state[1].dest); + fz_drop_pixmap(ctx, state[1].dest); if (state[0].shape != state[1].shape) { if (state[0].shape) fz_paint_pixmap(state[0].shape, state[1].shape, 255); - fz_drop_pixmap(dev->ctx, state[1].shape); + fz_drop_pixmap(ctx, state[1].shape); } #ifdef DUMP_GROUP_BLENDS - fz_dump_blend(dev->ctx, state[0].dest, " to get "); + fz_dump_blend(ctx, state[0].dest, " to get "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[0].shape, "/"); printf("\n"); #endif } static void -fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, const fz_matrix *ctm, +fz_draw_fill_path(fz_context *ctx, fz_device *devp, fz_path *path, int even_odd, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; + fz_gel *gel = dev->gel; + float expansion = fz_matrix_expansion(ctm); float flatness = 0.3f / expansion; unsigned char colorbv[FZ_MAX_COLORS + 1]; @@ -284,48 +282,50 @@ fz_draw_fill_path(fz_device *devp, fz_path *path, int even_odd, const fz_matrix fz_colorspace *model = state->dest->colorspace; if (model == NULL) - model = fz_device_gray(dev->ctx); + model = fz_device_gray(ctx); if (flatness < 0.001f) flatness = 0.001f; - fz_reset_gel(dev->gel, &state->scissor); - fz_flatten_fill_path(dev->gel, path, ctm, flatness); - fz_sort_gel(dev->gel); + fz_reset_gel(ctx, gel, &state->scissor); + fz_flatten_fill_path(ctx, gel, path, ctm, flatness); + fz_sort_gel(ctx, gel); - fz_intersect_irect(fz_bound_gel(dev->gel, &bbox), &state->scissor); + fz_intersect_irect(fz_bound_gel(ctx, gel, &bbox), &state->scissor); if (fz_is_empty_irect(&bbox)) return; if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + state = fz_knockout_begin(ctx, dev); - fz_convert_color(dev->ctx, model, colorfv, colorspace, color); + fz_convert_color(ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_scan_convert(dev->gel, even_odd, &bbox, state->dest, colorbv); + fz_scan_convert(ctx, gel, even_odd, &bbox, state->dest, colorbv); if (state->shape) { - fz_reset_gel(dev->gel, &state->scissor); - fz_flatten_fill_path(dev->gel, path, ctm, flatness); - fz_sort_gel(dev->gel); + fz_reset_gel(ctx, gel, &state->scissor); + fz_flatten_fill_path(ctx, gel, path, ctm, flatness); + fz_sort_gel(ctx, gel); colorbv[0] = alpha * 255; - fz_scan_convert(dev->gel, even_odd, &bbox, state->shape, colorbv); + fz_scan_convert(ctx, gel, even_odd, &bbox, state->shape, colorbv); } if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } static void -fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, const fz_matrix *ctm, +fz_draw_stroke_path(fz_context *ctx, fz_device *devp, fz_path *path, fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; + fz_gel *gel = dev->gel; + float expansion = fz_matrix_expansion(ctm); float flatness = 0.3f / expansion; float linewidth = stroke->linewidth; @@ -337,81 +337,82 @@ fz_draw_stroke_path(fz_device *devp, fz_path *path, fz_stroke_state *stroke, con fz_colorspace *model = state->dest->colorspace; if (model == NULL) - model = fz_device_gray(dev->ctx); + model = fz_device_gray(ctx); if (linewidth * expansion < 0.1f) linewidth = 1 / expansion; if (flatness < 0.001f) flatness = 0.001f; - fz_reset_gel(dev->gel, &state->scissor); + fz_reset_gel(ctx, gel, &state->scissor); if (stroke->dash_len > 0) - fz_flatten_dash_path(dev->gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_dash_path(ctx, gel, path, stroke, ctm, flatness, linewidth); else - fz_flatten_stroke_path(dev->gel, path, stroke, ctm, flatness, linewidth); - fz_sort_gel(dev->gel); + fz_flatten_stroke_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_sort_gel(ctx, gel); - fz_intersect_irect(fz_bound_gel(dev->gel, &bbox), &state->scissor); + fz_intersect_irect(fz_bound_gel(ctx, gel, &bbox), &state->scissor); if (fz_is_empty_irect(&bbox)) return; if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + state = fz_knockout_begin(ctx, dev); - fz_convert_color(dev->ctx, model, colorfv, colorspace, color); + fz_convert_color(ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_scan_convert(dev->gel, 0, &bbox, state->dest, colorbv); + fz_scan_convert(ctx, gel, 0, &bbox, state->dest, colorbv); if (state->shape) { - fz_reset_gel(dev->gel, &state->scissor); + fz_reset_gel(ctx, gel, &state->scissor); if (stroke->dash_len > 0) - fz_flatten_dash_path(dev->gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_dash_path(ctx, gel, path, stroke, ctm, flatness, linewidth); else - fz_flatten_stroke_path(dev->gel, path, stroke, ctm, flatness, linewidth); - fz_sort_gel(dev->gel); + fz_flatten_stroke_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_sort_gel(ctx, gel); colorbv[0] = 255; - fz_scan_convert(dev->gel, 0, &bbox, state->shape, colorbv); + fz_scan_convert(ctx, gel, 0, &bbox, state->shape, colorbv); } if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } static void -fz_draw_clip_path(fz_device *devp, fz_path *path, const fz_rect *rect, int even_odd, const fz_matrix *ctm) +fz_draw_clip_path(fz_context *ctx, fz_device *devp, fz_path *path, const fz_rect *rect, int even_odd, const fz_matrix *ctm) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; + fz_gel *gel = dev->gel; + float expansion = fz_matrix_expansion(ctm); float flatness = 0.3f / expansion; fz_irect bbox; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model; - fz_context *ctx = dev->ctx; if (flatness < 0.001f) flatness = 0.001f; - fz_reset_gel(dev->gel, &state->scissor); - fz_flatten_fill_path(dev->gel, path, ctm, flatness); - fz_sort_gel(dev->gel); + fz_reset_gel(ctx, gel, &state->scissor); + fz_flatten_fill_path(ctx, gel, path, ctm, flatness); + fz_sort_gel(ctx, gel); - state = push_stack(dev); + state = push_stack(ctx, dev); STACK_PUSHED("clip path"); model = state->dest->colorspace; - fz_intersect_irect(fz_bound_gel(dev->gel, &bbox), &state->scissor); + fz_intersect_irect(fz_bound_gel(ctx, gel, &bbox), &state->scissor); if (rect) { fz_irect bbox2; fz_intersect_irect(&bbox, fz_irect_from_rect(&bbox2, rect)); } - if (fz_is_empty_irect(&bbox) || fz_is_rect_gel(dev->gel)) + if (fz_is_empty_irect(&bbox) || fz_is_rect_gel(ctx, gel)) { state[1].scissor = bbox; state[1].mask = NULL; @@ -423,17 +424,17 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, const fz_rect *rect, int even_ fz_try(ctx) { - state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, state[1].mask); - state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); - fz_clear_pixmap(dev->ctx, state[1].dest); + state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, state[1].mask); + state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox); + fz_clear_pixmap(ctx, state[1].dest); if (state[1].shape) { - state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, state[1].shape); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, state[1].shape); } - fz_scan_convert(dev->gel, even_odd, &bbox, state[1].mask, NULL); + fz_scan_convert(ctx, gel, even_odd, &bbox, state[1].mask, NULL); state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].scissor = bbox; @@ -443,39 +444,40 @@ fz_draw_clip_path(fz_device *devp, fz_path *path, const fz_rect *rect, int even_ } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } } static void -fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, const fz_rect *rect, fz_stroke_state *stroke, const fz_matrix *ctm) +fz_draw_clip_stroke_path(fz_context *ctx, fz_device *devp, fz_path *path, const fz_rect *rect, fz_stroke_state *stroke, const fz_matrix *ctm) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; + fz_gel *gel = dev->gel; + float expansion = fz_matrix_expansion(ctm); float flatness = 0.3f / expansion; float linewidth = stroke->linewidth; fz_irect bbox; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model; - fz_context *ctx = dev->ctx; if (linewidth * expansion < 0.1f) linewidth = 1 / expansion; if (flatness < 0.001f) flatness = 0.001f; - fz_reset_gel(dev->gel, &state->scissor); + fz_reset_gel(ctx, gel, &state->scissor); if (stroke->dash_len > 0) - fz_flatten_dash_path(dev->gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_dash_path(ctx, gel, path, stroke, ctm, flatness, linewidth); else - fz_flatten_stroke_path(dev->gel, path, stroke, ctm, flatness, linewidth); - fz_sort_gel(dev->gel); + fz_flatten_stroke_path(ctx, gel, path, stroke, ctm, flatness, linewidth); + fz_sort_gel(ctx, gel); - state = push_stack(dev); + state = push_stack(ctx, dev); STACK_PUSHED("clip stroke"); model = state->dest->colorspace; - fz_intersect_irect(fz_bound_gel(dev->gel, &bbox), &state->scissor); + fz_intersect_irect(fz_bound_gel(ctx, gel, &bbox), &state->scissor); if (rect) { fz_irect bbox2; @@ -484,18 +486,18 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, const fz_rect *rect, fz fz_try(ctx) { - state[1].mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, state[1].mask); - state[1].dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); - fz_clear_pixmap(dev->ctx, state[1].dest); + state[1].mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, state[1].mask); + state[1].dest = fz_new_pixmap_with_bbox(ctx, model, &bbox); + fz_clear_pixmap(ctx, state[1].dest); if (state->shape) { - state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, state[1].shape); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, state[1].shape); } if (!fz_is_empty_irect(&bbox)) - fz_scan_convert(dev->gel, 0, &bbox, state[1].mask, NULL); + fz_scan_convert(ctx, gel, 0, &bbox, state[1].mask, NULL); state[1].blendmode |= FZ_BLEND_ISOLATED; state[1].scissor = bbox; @@ -505,7 +507,7 @@ fz_draw_clip_stroke_path(fz_device *devp, fz_path *path, const fz_rect *rect, fz } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } } @@ -558,10 +560,11 @@ draw_glyph(unsigned char *colorbv, fz_pixmap *dst, fz_glyph *glyph, } static void -fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, +fz_draw_fill_text(fz_context *ctx, fz_device *devp, fz_text *text, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; + unsigned char colorbv[FZ_MAX_COLORS + 1]; unsigned char shapebv; float colorfv[FZ_MAX_COLORS]; @@ -572,9 +575,9 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, fz_colorspace *model = state->dest->colorspace; if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + state = fz_knockout_begin(ctx, dev); - fz_convert_color(dev->ctx, model, colorfv, colorspace, color); + fz_convert_color(ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -592,7 +595,7 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - glyph = fz_render_glyph(dev->ctx, text->font, gid, &trm, model, &state->scissor); + glyph = fz_render_glyph(ctx, text->font, gid, &trm, model, &state->scissor); if (glyph) { fz_pixmap *pixmap = glyph->pixmap; @@ -611,33 +614,34 @@ fz_draw_fill_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, mat.e = x + pixmap->x; mat.f = y + pixmap->y; fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &mat, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)); } - fz_drop_glyph(dev->ctx, glyph); + fz_drop_glyph(ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &tm); + fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm); if (path) { - fz_draw_fill_path(devp, path, 0, ctm, colorspace, color, alpha); - fz_free_path(dev->ctx, path); + fz_draw_fill_path(ctx, devp, path, 0, ctm, colorspace, color, alpha); + fz_drop_path(ctx, path); } else { - fz_warn(dev->ctx, "cannot render glyph"); + fz_warn(ctx, "cannot render glyph"); } } } if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } static void -fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, +fz_draw_stroke_text(fz_context *ctx, fz_device *devp, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; + unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; fz_matrix tm, trm; @@ -647,9 +651,9 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_colorspace *model = state->dest->colorspace; if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + state = fz_knockout_begin(ctx, dev); - fz_convert_color(dev->ctx, model, colorfv, colorspace, color); + fz_convert_color(ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -666,7 +670,7 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trm, ctm, stroke, &state->scissor); + glyph = fz_render_stroked_glyph(ctx, text->font, gid, &trm, ctm, stroke, &state->scissor); if (glyph) { int x = (int)trm.e; @@ -674,32 +678,31 @@ fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, draw_glyph(colorbv, state->dest, glyph, x, y, &state->scissor); if (state->shape) draw_glyph(colorbv, state->shape, glyph, x, y, &state->scissor); - fz_drop_glyph(dev->ctx, glyph); + fz_drop_glyph(ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &tm); + fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm); if (path) { - fz_draw_stroke_path(devp, path, stroke, ctm, colorspace, color, alpha); - fz_free_path(dev->ctx, path); + fz_draw_stroke_path(ctx, devp, path, stroke, ctm, colorspace, color, alpha); + fz_drop_path(ctx, path); } else { - fz_warn(dev->ctx, "cannot render glyph"); + fz_warn(ctx, "cannot render glyph"); } } } if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } static void -fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accumulate) +fz_draw_clip_text(fz_context *ctx, fz_device *devp, fz_text *text, const fz_matrix *ctm, int accumulate) { - fz_draw_device *dev = devp->user; - fz_context *ctx = dev->ctx; + fz_draw_device *dev = (fz_draw_device*)devp; fz_irect bbox; fz_pixmap *mask, *dest, *shape; fz_matrix tm, trm; @@ -712,7 +715,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu /* 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 */ - state = push_stack(dev); + state = push_stack(ctx, dev); STACK_PUSHED("clip text"); model = state->dest->colorspace; @@ -721,7 +724,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu /* make the mask the exact size needed */ fz_rect rect; - fz_irect_from_rect(&bbox, fz_bound_text(dev->ctx, text, NULL, ctm, &rect)); + fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, NULL, ctm, &rect)); fz_intersect_irect(&bbox, &state->scissor); } else @@ -734,14 +737,14 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu { if (accumulate == 0 || accumulate == 1) { - mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, mask); - dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); - fz_clear_pixmap(dev->ctx, dest); + mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, mask); + dest = fz_new_pixmap_with_bbox(ctx, model, &bbox); + fz_clear_pixmap(ctx, dest); if (state->shape) { - shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, shape); + shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, shape); } else shape = NULL; @@ -776,7 +779,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - glyph = fz_render_glyph(dev->ctx, text->font, gid, &trm, model, &state->scissor); + glyph = fz_render_glyph(ctx, text->font, gid, &trm, model, &state->scissor); if (glyph) { int x = (int)trm.e; @@ -784,11 +787,11 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu draw_glyph(NULL, mask, glyph, x, y, &bbox); if (state[1].shape) draw_glyph(NULL, state[1].shape, glyph, x, y, &bbox); - fz_drop_glyph(dev->ctx, glyph); + fz_drop_glyph(ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &tm); + fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm); if (path) { fz_pixmap *old_dest; @@ -799,13 +802,13 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu state[1].mask = NULL; fz_try(ctx) { - fz_draw_fill_path(devp, path, 0, ctm, fz_device_gray(ctx), &white, 1); + fz_draw_fill_path(ctx, devp, path, 0, ctm, fz_device_gray(ctx), &white, 1); } fz_always(ctx) { state[1].mask = state[1].dest; state[1].dest = old_dest; - fz_free_path(dev->ctx, path); + fz_drop_path(ctx, path); } fz_catch(ctx) { @@ -814,7 +817,7 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu } else { - fz_warn(dev->ctx, "cannot render glyph for clipping"); + fz_warn(ctx, "cannot render glyph for clipping"); } } } @@ -823,40 +826,39 @@ fz_draw_clip_text(fz_device *devp, fz_text *text, const fz_matrix *ctm, int accu fz_catch(ctx) { if (accumulate == 0 || accumulate == 1) - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); fz_rethrow(ctx); } } static void -fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm) +fz_draw_clip_stroke_text(fz_context *ctx, fz_device *devp, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm) { - fz_draw_device *dev = devp->user; - fz_context *ctx = dev->ctx; + fz_draw_device *dev = (fz_draw_device*)devp; fz_irect bbox; fz_pixmap *mask, *dest, *shape; fz_matrix tm, trm; fz_glyph *glyph; int i, gid; - fz_draw_state *state = push_stack(dev); + fz_draw_state *state = push_stack(ctx, dev); fz_colorspace *model = state->dest->colorspace; fz_rect rect; STACK_PUSHED("clip stroke text"); /* make the mask the exact size needed */ - fz_irect_from_rect(&bbox, fz_bound_text(dev->ctx, text, stroke, ctm, &rect)); + fz_irect_from_rect(&bbox, fz_bound_text(ctx, text, stroke, ctm, &rect)); fz_intersect_irect(&bbox, &state->scissor); fz_try(ctx) { - state[1].mask = mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, mask); - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); - fz_clear_pixmap(dev->ctx, dest); + state[1].mask = mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, mask); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox); + fz_clear_pixmap(ctx, dest); if (state->shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, shape); + state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, shape); } else shape = state->shape; @@ -881,7 +883,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke tm.f = text->items[i].y; fz_concat(&trm, &tm, ctm); - glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, &trm, ctm, stroke, &state->scissor); + glyph = fz_render_stroked_glyph(ctx, text->font, gid, &trm, ctm, stroke, &state->scissor); if (glyph) { int x = (int)trm.e; @@ -889,11 +891,11 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke draw_glyph(NULL, mask, glyph, x, y, &bbox); if (shape) draw_glyph(NULL, shape, glyph, x, y, &bbox); - fz_drop_glyph(dev->ctx, glyph); + fz_drop_glyph(ctx, glyph); } else { - fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, &tm); + fz_path *path = fz_outline_glyph(ctx, text->font, gid, &tm); if (path) { fz_pixmap *old_dest; @@ -905,13 +907,13 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke state[0].mask = NULL; fz_try(ctx) { - fz_draw_stroke_path(devp, path, stroke, ctm, fz_device_gray(ctx), &white, 1); + fz_draw_stroke_path(ctx, devp, path, stroke, ctm, fz_device_gray(ctx), &white, 1); } fz_always(ctx) { state[0].mask = state[0].dest; state[0].dest = old_dest; - fz_free_path(dev->ctx, path); + fz_drop_path(ctx, path); } fz_catch(ctx) { @@ -920,7 +922,7 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke } else { - fz_warn(dev->ctx, "cannot render glyph for stroked clipping"); + fz_warn(ctx, "cannot render glyph for stroked clipping"); } } } @@ -928,19 +930,19 @@ fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } } static void -fz_draw_ignore_text(fz_device *dev, fz_text *text, const fz_matrix *ctm) +fz_draw_ignore_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm) { } static void -fz_draw_fill_shade(fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float alpha) +fz_draw_fill_shade(fz_context *ctx, fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; fz_rect bounds; fz_irect bbox, scissor; fz_pixmap *dest, *shape; @@ -949,7 +951,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; - fz_bound_shade(dev->ctx, shade, ctm, &bounds); + fz_bound_shade(ctx, shade, ctm, &bounds); scissor = state->scissor; fz_intersect_irect(fz_irect_from_rect(&bbox, &bounds), &scissor); @@ -958,24 +960,24 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float if (!model) { - fz_warn(dev->ctx, "cannot render shading directly to an alpha mask"); + fz_warn(ctx, "cannot render shading directly to an alpha mask"); return; } if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + state = fz_knockout_begin(ctx, dev); dest = state->dest; shape = state->shape; if (alpha < 1) { - dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, &bbox); - fz_clear_pixmap(dev->ctx, dest); + dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox); + fz_clear_pixmap(ctx, dest); if (shape) { - shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, shape); + shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, shape); } } @@ -983,7 +985,7 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float { unsigned char *s; int x, y, n, i; - fz_convert_color(dev->ctx, model, colorfv, shade->colorspace, shade->background); + fz_convert_color(ctx, model, colorfv, shade->colorspace, shade->background); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = 255; @@ -1011,30 +1013,29 @@ fz_draw_fill_shade(fz_device *devp, fz_shade *shade, const fz_matrix *ctm, float } } - fz_paint_shade(dev->ctx, shade, ctm, dest, &bbox); + fz_paint_shade(ctx, shade, ctm, dest, &bbox); if (shape) - fz_clear_pixmap_rect_with_value(dev->ctx, shape, 255, &bbox); + fz_clear_pixmap_rect_with_value(ctx, shape, 255, &bbox); if (alpha < 1) { fz_paint_pixmap(state->dest, dest, alpha * 255); - fz_drop_pixmap(dev->ctx, dest); + fz_drop_pixmap(ctx, dest); if (shape) { fz_paint_pixmap(state->shape, shape, alpha * 255); - fz_drop_pixmap(dev->ctx, shape); + fz_drop_pixmap(ctx, shape); } } if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } static fz_pixmap * -fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy, int gridfit, const fz_irect *clip) +fz_transform_pixmap(fz_context *ctx, fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x, int y, int dx, int dy, int gridfit, const fz_irect *clip) { fz_pixmap *scaled; - fz_context *ctx = dev->ctx; if (ctm->a != 0 && ctm->b == 0 && ctm->c == 0 && ctm->d != 0) { @@ -1087,16 +1088,15 @@ fz_transform_pixmap(fz_draw_device *dev, fz_pixmap *image, fz_matrix *ctm, int x } static void -fz_draw_fill_image(fz_device *devp, fz_image *image, const fz_matrix *ctm, float alpha) +fz_draw_fill_image(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *ctm, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; fz_pixmap *converted = NULL; fz_pixmap *scaled = NULL; fz_pixmap *pixmap; fz_pixmap *orig_pixmap; int after; int dx, dy; - fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; fz_irect clip; @@ -1108,7 +1108,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, const fz_matrix *ctm, float if (!model) { - fz_warn(dev->ctx, "cannot render image directly to an alpha mask"); + fz_warn(ctx, "cannot render image directly to an alpha mask"); return; } @@ -1128,7 +1128,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, const fz_matrix *ctm, float fz_try(ctx) { if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + state = fz_knockout_begin(ctx, dev); after = 0; if (pixmap->colorspace == fz_device_gray(ctx)) @@ -1146,7 +1146,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, const fz_matrix *ctm, float if (dx < pixmap->w && dy < pixmap->h && !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) @@ -1179,7 +1179,7 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, const fz_matrix *ctm, float fz_paint_image(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, alpha * 255, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)); if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } fz_always(ctx) { @@ -1194,10 +1194,10 @@ fz_draw_fill_image(fz_device *devp, fz_image *image, const fz_matrix *ctm, float } static void -fz_draw_fill_image_mask(fz_device *devp, fz_image *image, const fz_matrix *ctm, +fz_draw_fill_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; unsigned char colorbv[FZ_MAX_COLORS + 1]; float colorfv[FZ_MAX_COLORS]; fz_pixmap *scaled = NULL; @@ -1205,7 +1205,6 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, const fz_matrix *ctm, fz_pixmap *orig_pixmap; int dx, dy; int i; - fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; fz_irect clip; @@ -1225,25 +1224,25 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, const fz_matrix *ctm, fz_try(ctx) { if (state->blendmode & FZ_BLEND_KNOCKOUT) - state = fz_knockout_begin(dev); + state = fz_knockout_begin(ctx, dev); if (dx < pixmap->w && dy < pixmap->h) { int gridfit = alpha == 1.0f && !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; - scaled = fz_scale_pixmap_cached(dev->ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL, dev->cache_x, dev->cache_y); + scaled = fz_scale_pixmap_cached(ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL, dev->cache_x, dev->cache_y); } if (scaled) pixmap = scaled; } - fz_convert_color(dev->ctx, model, colorfv, colorspace, color); + fz_convert_color(ctx, model, colorfv, colorspace, color); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; @@ -1251,14 +1250,14 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, const fz_matrix *ctm, fz_paint_image_with_color(state->dest, &state->scissor, state->shape, pixmap, &local_ctm, colorbv, !(devp->hints & FZ_DONT_INTERPOLATE_IMAGES)); if (scaled) - fz_drop_pixmap(dev->ctx, scaled); + fz_drop_pixmap(ctx, scaled); if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } fz_always(ctx) { - fz_drop_pixmap(dev->ctx, orig_pixmap); + fz_drop_pixmap(ctx, orig_pixmap); } fz_catch(ctx) { @@ -1267,10 +1266,9 @@ fz_draw_fill_image_mask(fz_device *devp, fz_image *image, const fz_matrix *ctm, } static void -fz_draw_clip_image_mask(fz_device *devp, fz_image *image, const fz_rect *rect, const fz_matrix *ctm) +fz_draw_clip_image_mask(fz_context *ctx, fz_device *devp, fz_image *image, const fz_rect *rect, const fz_matrix *ctm) { - fz_draw_device *dev = devp->user; - fz_context *ctx = dev->ctx; + fz_draw_device *dev = (fz_draw_device*)devp; fz_irect bbox; fz_pixmap *mask = NULL; fz_pixmap *dest = NULL; @@ -1279,7 +1277,7 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, const fz_rect *rect, c fz_pixmap *pixmap = NULL; fz_pixmap *orig_pixmap = NULL; int dx, dy; - fz_draw_state *state = push_stack(dev); + fz_draw_state *state = push_stack(ctx, dev); fz_colorspace *model = state->dest->colorspace; fz_irect clip; fz_matrix local_ctm = *ctm; @@ -1326,15 +1324,15 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, const fz_rect *rect, c pixmap = fz_new_pixmap_from_image(ctx, image, dx, dy); orig_pixmap = pixmap; - state[1].mask = mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, mask); + state[1].mask = mask = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, mask); - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); - fz_clear_pixmap(dev->ctx, dest); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox); + fz_clear_pixmap(ctx, dest); if (state->shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, shape); + state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, shape); } state[1].blendmode |= FZ_BLEND_ISOLATED; @@ -1343,14 +1341,14 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, const fz_rect *rect, c if (dx < pixmap->w && dy < pixmap->h) { int gridfit = !(dev->flags & FZ_DRAWDEV_FLAGS_TYPE3); - scaled = fz_transform_pixmap(dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); + scaled = fz_transform_pixmap(ctx, dev, pixmap, &local_ctm, state->dest->x, state->dest->y, dx, dy, gridfit, &clip); if (!scaled) { if (dx < 1) dx = 1; if (dy < 1) dy = 1; - scaled = fz_scale_pixmap_cached(dev->ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL, dev->cache_x, dev->cache_y); + scaled = fz_scale_pixmap_cached(ctx, pixmap, pixmap->x, pixmap->y, dx, dy, NULL, dev->cache_x, dev->cache_y); } if (scaled) pixmap = scaled; @@ -1364,15 +1362,14 @@ fz_draw_clip_image_mask(fz_device *devp, fz_image *image, const fz_rect *rect, c } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } } static void -fz_draw_pop_clip(fz_device *devp) +fz_draw_pop_clip(fz_context *ctx, fz_device *devp) { - fz_draw_device *dev = devp->user; - fz_context *ctx = dev->ctx; + fz_draw_device *dev = (fz_draw_device*)devp; fz_draw_state *state; if (dev->top == 0) @@ -1390,31 +1387,31 @@ fz_draw_pop_clip(fz_device *devp) { #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top, ""); - fz_dump_blend(dev->ctx, state[1].dest, "Clipping "); + fz_dump_blend(ctx, state[1].dest, "Clipping "); if (state[1].shape) - fz_dump_blend(dev->ctx, state[1].shape, "/"); - fz_dump_blend(dev->ctx, state[0].dest, " onto "); + fz_dump_blend(ctx, state[1].shape, "/"); + fz_dump_blend(ctx, state[0].dest, " onto "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); - fz_dump_blend(dev->ctx, state[1].mask, " with "); + fz_dump_blend(ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[1].mask, " with "); #endif fz_paint_pixmap_with_mask(state[0].dest, state[1].dest, state[1].mask); if (state[0].shape != state[1].shape) { fz_paint_pixmap_with_mask(state[0].shape, state[1].shape, state[1].mask); - fz_drop_pixmap(dev->ctx, state[1].shape); + fz_drop_pixmap(ctx, state[1].shape); } /* The following tests should not be required, but just occasionally * errors can cause the stack to get out of sync, and this might save * our bacon. */ if (state[0].mask != state[1].mask) - fz_drop_pixmap(dev->ctx, state[1].mask); + fz_drop_pixmap(ctx, state[1].mask); if (state[0].dest != state[1].dest) - fz_drop_pixmap(dev->ctx, state[1].dest); + fz_drop_pixmap(ctx, state[1].dest); #ifdef DUMP_GROUP_BLENDS - fz_dump_blend(dev->ctx, state[0].dest, " to get "); + fz_dump_blend(ctx, state[0].dest, " to get "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[0].shape, "/"); printf("\n"); #endif } @@ -1427,21 +1424,20 @@ fz_draw_pop_clip(fz_device *devp) } static void -fz_draw_begin_mask(fz_device *devp, const fz_rect *rect, int luminosity, fz_colorspace *colorspace, float *colorfv) +fz_draw_begin_mask(fz_context *ctx, fz_device *devp, const fz_rect *rect, int luminosity, fz_colorspace *colorspace, float *colorfv) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; fz_pixmap *dest; fz_irect bbox; - fz_draw_state *state = push_stack(dev); + fz_draw_state *state = push_stack(ctx, dev); fz_pixmap *shape = state->shape; - fz_context *ctx = dev->ctx; STACK_PUSHED("mask"); fz_intersect_irect(fz_irect_from_rect(&bbox, rect), &state->scissor); fz_try(ctx) { - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, fz_device_gray(ctx), &bbox); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, fz_device_gray(ctx), &bbox); if (state->shape) { /* FIXME: If we ever want to support AIS true, then @@ -1458,16 +1454,16 @@ fz_draw_begin_mask(fz_device *devp, const fz_rect *rect, int luminosity, fz_colo float bc; if (!colorspace) colorspace = fz_device_gray(ctx); - fz_convert_color(dev->ctx, fz_device_gray(ctx), &bc, colorspace, colorfv); - fz_clear_pixmap_with_value(dev->ctx, dest, bc * 255); + fz_convert_color(ctx, fz_device_gray(ctx), &bc, colorspace, colorfv); + fz_clear_pixmap_with_value(ctx, dest, bc * 255); if (shape) - fz_clear_pixmap_with_value(dev->ctx, shape, 255); + fz_clear_pixmap_with_value(ctx, shape, 255); } else { - fz_clear_pixmap(dev->ctx, dest); + fz_clear_pixmap(ctx, dest); if (shape) - fz_clear_pixmap(dev->ctx, shape); + fz_clear_pixmap(ctx, shape); } #ifdef DUMP_GROUP_BLENDS @@ -1478,18 +1474,17 @@ fz_draw_begin_mask(fz_device *devp, const fz_rect *rect, int luminosity, fz_colo } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } } static void -fz_draw_end_mask(fz_device *devp) +fz_draw_end_mask(fz_context *ctx, fz_device *devp) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; fz_pixmap *temp, *dest; fz_irect bbox; int luminosity; - fz_context *ctx = dev->ctx; fz_draw_state *state; if (dev->top == 0) @@ -1508,21 +1503,21 @@ fz_draw_end_mask(fz_device *devp) fz_try(ctx) { /* convert to alpha mask */ - temp = fz_alpha_from_gray(dev->ctx, state[1].dest, luminosity); + temp = fz_alpha_from_gray(ctx, state[1].dest, luminosity); if (state[1].mask != state[0].mask) - fz_drop_pixmap(dev->ctx, state[1].mask); + fz_drop_pixmap(ctx, state[1].mask); state[1].mask = temp; if (state[1].dest != state[0].dest) - fz_drop_pixmap(dev->ctx, state[1].dest); + fz_drop_pixmap(ctx, state[1].dest); state[1].dest = NULL; if (state[1].shape != state[0].shape) - fz_drop_pixmap(dev->ctx, state[1].shape); + fz_drop_pixmap(ctx, state[1].shape); state[1].shape = NULL; /* create new dest scratch buffer */ fz_pixmap_bbox(ctx, temp, &bbox); - dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, &bbox); - fz_clear_pixmap(dev->ctx, dest); + dest = fz_new_pixmap_with_bbox(ctx, state->dest->colorspace, &bbox); + fz_clear_pixmap(ctx, dest); /* push soft mask as clip mask */ state[1].dest = dest; @@ -1531,31 +1526,30 @@ fz_draw_end_mask(fz_device *devp) * clip mask when we pop. So create a new shape now. */ if (state[0].shape) { - state[1].shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, state[1].shape); + state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); + fz_clear_pixmap(ctx, state[1].shape); } state[1].scissor = bbox; } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } } static void -fz_draw_begin_group(fz_device *devp, const fz_rect *rect, int isolated, int knockout, int blendmode, float alpha) +fz_draw_begin_group(fz_context *ctx, fz_device *devp, const fz_rect *rect, int isolated, int knockout, int blendmode, float alpha) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; fz_irect bbox; fz_pixmap *dest; - fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_begin(dev); + fz_knockout_begin(ctx, dev); - state = push_stack(dev); + state = push_stack(ctx, dev); STACK_PUSHED("group"); fz_intersect_irect(fz_irect_from_rect(&bbox, rect), &state->scissor); @@ -1570,11 +1564,11 @@ fz_draw_begin_group(fz_device *devp, const fz_rect *rect, int isolated, int knoc if (isolated) { - fz_clear_pixmap(dev->ctx, dest); + fz_clear_pixmap(ctx, dest); } else { - fz_copy_pixmap_rect(dev->ctx, dest, state[0].dest, &bbox); + fz_copy_pixmap_rect(ctx, dest, state[0].dest, &bbox); } if (blendmode == 0 && alpha == 1.0 && isolated) @@ -1586,7 +1580,7 @@ fz_draw_begin_group(fz_device *devp, const fz_rect *rect, int isolated, int knoc else { state[1].shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); - fz_clear_pixmap(dev->ctx, state[1].shape); + fz_clear_pixmap(ctx, state[1].shape); } state[1].alpha = alpha; @@ -1599,18 +1593,17 @@ fz_draw_begin_group(fz_device *devp, const fz_rect *rect, int isolated, int knoc } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } } static void -fz_draw_end_group(fz_device *devp) +fz_draw_end_group(fz_context *ctx, fz_device *devp) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; int blendmode; int isolated; float alpha; - fz_context *ctx = dev->ctx; fz_draw_state *state; if (dev->top == 0) @@ -1626,12 +1619,12 @@ fz_draw_end_group(fz_device *devp) isolated = state[1].blendmode & FZ_BLEND_ISOLATED; #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top, ""); - fz_dump_blend(dev->ctx, state[1].dest, "Group end: blending "); + fz_dump_blend(ctx, state[1].dest, "Group end: blending "); if (state[1].shape) - fz_dump_blend(dev->ctx, state[1].shape, "/"); - fz_dump_blend(dev->ctx, state[0].dest, " onto "); + fz_dump_blend(ctx, state[1].shape, "/"); + fz_dump_blend(ctx, state[0].dest, " onto "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[0].shape, "/"); if (alpha != 1.0f) printf(" (alpha %g)", alpha); if (blendmode != 0) @@ -1650,22 +1643,22 @@ fz_draw_end_group(fz_device *devp) * errors can cause the stack to get out of sync, and this might save * our bacon. */ if (state[0].dest != state[1].dest) - fz_drop_pixmap(dev->ctx, state[1].dest); + fz_drop_pixmap(ctx, state[1].dest); if (state[0].shape != state[1].shape) { if (state[0].shape) fz_paint_pixmap(state[0].shape, state[1].shape, alpha * 255); - fz_drop_pixmap(dev->ctx, state[1].shape); + fz_drop_pixmap(ctx, state[1].shape); } #ifdef DUMP_GROUP_BLENDS - fz_dump_blend(dev->ctx, state[0].dest, " to get "); + fz_dump_blend(ctx, state[0].dest, " to get "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[0].shape, "/"); printf("\n"); #endif if (state[0].blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } typedef struct @@ -1683,7 +1676,7 @@ typedef struct } tile_record; static int -fz_make_hash_tile_key(fz_store_hash *hash, void *key_) +fz_make_hash_tile_key(fz_context *ctx, fz_store_hash *hash, void *key_) { tile_key *key = (tile_key *)key_; @@ -1699,44 +1692,30 @@ static void * fz_keep_tile_key(fz_context *ctx, void *key_) { tile_key *key = (tile_key *)key_; - - fz_lock(ctx, FZ_LOCK_ALLOC); - key->refs++; - fz_unlock(ctx, FZ_LOCK_ALLOC); - - return (void *)key; + return fz_keep_imp(ctx, key, &key->refs); } static void fz_drop_tile_key(fz_context *ctx, void *key_) { tile_key *key = (tile_key *)key_; - int drop; - - fz_lock(ctx, FZ_LOCK_ALLOC); - drop = --key->refs; - fz_unlock(ctx, FZ_LOCK_ALLOC); - if (drop == 0) - { + if (fz_drop_imp(ctx, key, &key->refs)) fz_free(ctx, key); - } } static int -fz_cmp_tile_key(void *k0_, void *k1_) +fz_cmp_tile_key(fz_context *ctx, void *k0_, void *k1_) { tile_key *k0 = (tile_key *)k0_; tile_key *k1 = (tile_key *)k1_; - return k0->id == k1->id && k0->ctm[0] == k1->ctm[0] && k0->ctm[1] == k1->ctm[1] && k0->ctm[2] == k1->ctm[2] && k0->ctm[3] == k1->ctm[3]; } #ifndef NDEBUG static void -fz_debug_tile(FILE *out, void *key_) +fz_debug_tile(fz_context *ctx, FILE *out, void *key_) { tile_key *key = (tile_key *)key_; - fprintf(out, "(tile id=%x, ctm=%g %g %g %g) ", key->id, key->ctm[0], key->ctm[1], key->ctm[2], key->ctm[3]); } #endif @@ -1753,12 +1732,9 @@ static fz_store_type fz_tile_store_type = }; static void -fz_free_tile_record_imp(fz_context *ctx, fz_storable *storable) +fz_drop_tile_record_imp(fz_context *ctx, fz_storable *storable) { - tile_record *tr = (tile_record *)(void *)storable; - - if (tr == NULL) - return; + tile_record *tr = (tile_record *)storable; fz_drop_pixmap(ctx, tr->dest); fz_drop_pixmap(ctx, tr->shape); fz_free(ctx, tr); @@ -1774,7 +1750,7 @@ static tile_record * fz_new_tile_record(fz_context *ctx, fz_pixmap *dest, fz_pixmap *shape) { tile_record *tile = fz_malloc_struct(ctx, tile_record); - FZ_INIT_STORABLE(tile, 1, fz_free_tile_record_imp); + FZ_INIT_STORABLE(tile, 1, fz_drop_tile_record_imp); tile->dest = fz_keep_pixmap(ctx, dest); tile->shape = fz_keep_pixmap(ctx, shape); return tile; @@ -1789,13 +1765,12 @@ fz_tile_size(fz_context *ctx, tile_record *tile) } static int -fz_draw_begin_tile(fz_device *devp, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id) +fz_draw_begin_tile(fz_context *ctx, fz_device *devp, const fz_rect *area, const fz_rect *view, float xstep, float ystep, const fz_matrix *ctm, int id) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; fz_pixmap *dest = NULL; fz_pixmap *shape; fz_irect bbox; - fz_context *ctx = dev->ctx; fz_draw_state *state = &dev->stack[dev->top]; fz_colorspace *model = state->dest->colorspace; fz_rect local_view = *view; @@ -1804,9 +1779,9 @@ fz_draw_begin_tile(fz_device *devp, const fz_rect *area, const fz_rect *view, fl /* ctm maps from pattern space to device space */ if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_begin(dev); + fz_knockout_begin(ctx, dev); - state = push_stack(dev); + state = push_stack(ctx, dev); STACK_PUSHED("tile"); fz_irect_from_rect(&bbox, fz_transform_rect(&local_view, ctm)); /* We should never have a bbox that entirely covers our destination. @@ -1828,7 +1803,7 @@ fz_draw_begin_tile(fz_device *devp, const fz_rect *area, const fz_rect *view, fl tk.ctm[3] = ctm->d; tk.id = id; - tile = fz_find_item(ctx, fz_free_tile_record_imp, &tk, &fz_tile_store_type); + tile = fz_find_item(ctx, fz_drop_tile_record_imp, &tk, &fz_tile_store_type); if (tile) { state[1].dest = fz_keep_pixmap(ctx, tile->dest); @@ -1851,12 +1826,12 @@ fz_draw_begin_tile(fz_device *devp, const fz_rect *area, const fz_rect *view, fl fz_try(ctx) { - state[1].dest = dest = fz_new_pixmap_with_bbox(dev->ctx, model, &bbox); + state[1].dest = dest = fz_new_pixmap_with_bbox(ctx, model, &bbox); fz_clear_pixmap(ctx, dest); shape = state[0].shape; if (shape) { - state[1].shape = shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, &bbox); + state[1].shape = shape = fz_new_pixmap_with_bbox(ctx, NULL, &bbox); fz_clear_pixmap(ctx, shape); } state[1].blendmode |= FZ_BLEND_ISOLATED; @@ -1873,22 +1848,21 @@ fz_draw_begin_tile(fz_device *devp, const fz_rect *area, const fz_rect *view, fl } fz_catch(ctx) { - emergency_pop_stack(dev, state); + emergency_pop_stack(ctx, dev, state); } return 0; } static void -fz_draw_end_tile(fz_device *devp) +fz_draw_end_tile(fz_context *ctx, fz_device *devp) { - fz_draw_device *dev = devp->user; + fz_draw_device *dev = (fz_draw_device*)devp; float xstep, ystep; fz_matrix ttm, ctm, shapectm; fz_irect area, scissor; fz_rect scissor_tmp; int x0, y0, x1, y1, x, y; - fz_context *ctx = dev->ctx; fz_draw_state *state; tile_record *tile; tile_key *key; @@ -1940,12 +1914,12 @@ fz_draw_end_tile(fz_device *devp) #ifdef DUMP_GROUP_BLENDS dump_spaces(dev->top, ""); - fz_dump_blend(dev->ctx, state[1].dest, "Tiling "); + fz_dump_blend(ctx, state[1].dest, "Tiling "); if (state[1].shape) - fz_dump_blend(dev->ctx, state[1].shape, "/"); - fz_dump_blend(dev->ctx, state[0].dest, " onto "); + fz_dump_blend(ctx, state[1].shape, "/"); + fz_dump_blend(ctx, state[0].dest, " onto "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[0].shape, "/"); #endif for (y = y0; y < y1; y++) @@ -2023,25 +1997,26 @@ fz_draw_end_tile(fz_device *devp) * errors can cause the stack to get out of sync, and this might save * our bacon. */ if (state[0].dest != state[1].dest) - fz_drop_pixmap(dev->ctx, state[1].dest); + fz_drop_pixmap(ctx, state[1].dest); if (state[0].shape != state[1].shape) - fz_drop_pixmap(dev->ctx, state[1].shape); + fz_drop_pixmap(ctx, state[1].shape); #ifdef DUMP_GROUP_BLENDS - fz_dump_blend(dev->ctx, state[0].dest, " to get "); + fz_dump_blend(ctx, state[0].dest, " to get "); if (state[0].shape) - fz_dump_blend(dev->ctx, state[0].shape, "/"); + fz_dump_blend(ctx, state[0].shape, "/"); printf("\n"); #endif if (state->blendmode & FZ_BLEND_KNOCKOUT) - fz_knockout_end(dev); + fz_knockout_end(ctx, dev); } static void -fz_draw_free_user(fz_device *devp) +fz_draw_drop_imp(fz_context *ctx, fz_device *devp) { - fz_draw_device *dev = devp->user; - fz_context *ctx = dev->ctx; + fz_draw_device *dev = (fz_draw_device*)devp; + fz_gel *gel = dev->gel; + /* pop and free the stacks */ if (dev->top > 0) fz_warn(ctx, "items left on stack in draw device: %d", dev->top+1); @@ -2062,103 +2037,95 @@ fz_draw_free_user(fz_device *devp) */ if (dev->stack != &dev->init_stack[0]) fz_free(ctx, dev->stack); - fz_free_scale_cache(ctx, dev->cache_x); - fz_free_scale_cache(ctx, dev->cache_y); - fz_free_gel(dev->gel); - fz_free(ctx, dev); + fz_drop_scale_cache(ctx, dev->cache_x); + fz_drop_scale_cache(ctx, dev->cache_y); + fz_drop_gel(ctx, gel); } fz_device * fz_new_draw_device(fz_context *ctx, fz_pixmap *dest) { - fz_device *dev = NULL; - fz_draw_device *ddev = fz_malloc_struct(ctx, fz_draw_device); + fz_draw_device *dev = fz_new_device(ctx, sizeof *dev); + + dev->super.drop_imp = fz_draw_drop_imp; + + dev->super.fill_path = fz_draw_fill_path; + dev->super.stroke_path = fz_draw_stroke_path; + dev->super.clip_path = fz_draw_clip_path; + dev->super.clip_stroke_path = fz_draw_clip_stroke_path; + + dev->super.fill_text = fz_draw_fill_text; + dev->super.stroke_text = fz_draw_stroke_text; + dev->super.clip_text = fz_draw_clip_text; + dev->super.clip_stroke_text = fz_draw_clip_stroke_text; + dev->super.ignore_text = fz_draw_ignore_text; + + dev->super.fill_image_mask = fz_draw_fill_image_mask; + dev->super.clip_image_mask = fz_draw_clip_image_mask; + dev->super.fill_image = fz_draw_fill_image; + dev->super.fill_shade = fz_draw_fill_shade; + + dev->super.pop_clip = fz_draw_pop_clip; + + dev->super.begin_mask = fz_draw_begin_mask; + dev->super.end_mask = fz_draw_end_mask; + dev->super.begin_group = fz_draw_begin_group; + dev->super.end_group = fz_draw_end_group; + + dev->super.begin_tile = fz_draw_begin_tile; + dev->super.end_tile = fz_draw_end_tile; + + dev->flags = 0; + dev->top = 0; + dev->stack = &dev->init_stack[0]; + dev->stack_cap = STACK_SIZE; + dev->stack[0].dest = dest; + dev->stack[0].shape = NULL; + dev->stack[0].mask = NULL; + dev->stack[0].blendmode = 0; + dev->stack[0].scissor.x0 = dest->x; + dev->stack[0].scissor.y0 = dest->y; + dev->stack[0].scissor.x1 = dest->x + dest->w; + dev->stack[0].scissor.y1 = dest->y + dest->h; - fz_var(dev); fz_try(ctx) { - ddev->gel = fz_new_gel(ctx); - ddev->flags = 0; - ddev->ctx = ctx; - ddev->top = 0; - ddev->cache_x = fz_new_scale_cache(ctx); - ddev->cache_y = fz_new_scale_cache(ctx); - ddev->stack = &ddev->init_stack[0]; - ddev->stack_cap = STACK_SIZE; - ddev->stack[0].dest = dest; - ddev->stack[0].shape = NULL; - ddev->stack[0].mask = NULL; - ddev->stack[0].blendmode = 0; - ddev->stack[0].scissor.x0 = dest->x; - ddev->stack[0].scissor.y0 = dest->y; - ddev->stack[0].scissor.x1 = dest->x + dest->w; - ddev->stack[0].scissor.y1 = dest->y + dest->h; - - dev = fz_new_device(ctx, ddev); + dev->gel = fz_new_gel(ctx); + dev->cache_x = fz_new_scale_cache(ctx); + dev->cache_y = fz_new_scale_cache(ctx); } fz_catch(ctx) { - fz_free_scale_cache(ctx, ddev->cache_x); - fz_free_scale_cache(ctx, ddev->cache_y); - fz_free_gel(ddev->gel); - fz_free(ctx, ddev); + fz_drop_device(ctx, (fz_device*)dev); fz_rethrow(ctx); } - dev->free_user = fz_draw_free_user; - - dev->fill_path = fz_draw_fill_path; - dev->stroke_path = fz_draw_stroke_path; - dev->clip_path = fz_draw_clip_path; - dev->clip_stroke_path = fz_draw_clip_stroke_path; - - dev->fill_text = fz_draw_fill_text; - dev->stroke_text = fz_draw_stroke_text; - dev->clip_text = fz_draw_clip_text; - dev->clip_stroke_text = fz_draw_clip_stroke_text; - dev->ignore_text = fz_draw_ignore_text; - - dev->fill_image_mask = fz_draw_fill_image_mask; - dev->clip_image_mask = fz_draw_clip_image_mask; - dev->fill_image = fz_draw_fill_image; - dev->fill_shade = fz_draw_fill_shade; - - dev->pop_clip = fz_draw_pop_clip; - - dev->begin_mask = fz_draw_begin_mask; - dev->end_mask = fz_draw_end_mask; - dev->begin_group = fz_draw_begin_group; - dev->end_group = fz_draw_end_group; - - dev->begin_tile = fz_draw_begin_tile; - dev->end_tile = fz_draw_end_tile; - return dev; + return (fz_device*)dev; } fz_device * fz_new_draw_device_with_bbox(fz_context *ctx, fz_pixmap *dest, const fz_irect *clip) { - fz_device *dev = fz_new_draw_device(ctx, dest); - fz_draw_device *ddev = dev->user; - - if (clip->x0 > ddev->stack[0].scissor.x0) - ddev->stack[0].scissor.x0 = clip->x0; - if (clip->x1 < ddev->stack[0].scissor.x1) - ddev->stack[0].scissor.x1 = clip->x1; - if (clip->y0 > ddev->stack[0].scissor.y0) - ddev->stack[0].scissor.y0 = clip->y0; - if (clip->y1 < ddev->stack[0].scissor.y1) - ddev->stack[0].scissor.y1 = clip->y1; - return dev; + fz_draw_device *dev = (fz_draw_device*)fz_new_draw_device(ctx, dest); + + if (clip->x0 > dev->stack[0].scissor.x0) + dev->stack[0].scissor.x0 = clip->x0; + if (clip->x1 < dev->stack[0].scissor.x1) + dev->stack[0].scissor.x1 = clip->x1; + if (clip->y0 > dev->stack[0].scissor.y0) + dev->stack[0].scissor.y0 = clip->y0; + if (clip->y1 < dev->stack[0].scissor.y1) + dev->stack[0].scissor.y1 = clip->y1; + + return (fz_device*)dev; } fz_device * fz_new_draw_device_type3(fz_context *ctx, fz_pixmap *dest) { - fz_device *dev = fz_new_draw_device(ctx, dest); - fz_draw_device *ddev = dev->user; - ddev->flags |= FZ_DRAWDEV_FLAGS_TYPE3; - return dev; + fz_draw_device *dev = (fz_draw_device*)fz_new_draw_device(ctx, dest); + dev->flags |= FZ_DRAWDEV_FLAGS_TYPE3; + return (fz_device*)dev; } fz_irect * @@ -2166,18 +2133,18 @@ fz_bound_path_accurate(fz_context *ctx, fz_irect *bbox, const fz_irect *scissor, { fz_gel *gel = fz_new_gel(ctx); - fz_reset_gel(gel, scissor); + fz_reset_gel(ctx, gel, scissor); if (stroke) { if (stroke->dash_len > 0) - fz_flatten_dash_path(gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_dash_path(ctx, gel, path, stroke, ctm, flatness, linewidth); else - fz_flatten_stroke_path(gel, path, stroke, ctm, flatness, linewidth); + fz_flatten_stroke_path(ctx, gel, path, stroke, ctm, flatness, linewidth); } else - fz_flatten_fill_path(gel, path, ctm, flatness); - fz_bound_gel(gel, bbox); - fz_free_gel(gel); + fz_flatten_fill_path(ctx, gel, path, ctm, flatness); + fz_bound_gel(ctx, gel, bbox); + fz_drop_gel(ctx, gel); return bbox; } |