Beispiel #1
0
static void
fz_draw_pop_clip(fz_context *ctx, void *user)
{
	fz_draw_device *dev = user;
	fz_pixmap *mask, *dest, *shape;
	if (dev->top > 0)
	{
		dev->top--;
		dev->scissor = dev->stack[dev->top].scissor;
		mask = dev->stack[dev->top].mask;
		dest = dev->stack[dev->top].dest;
		shape = dev->stack[dev->top].shape;
		dev->blendmode = dev->stack[dev->top].blendmode;

		/* We can get here with mask == NULL if the clipping actually
		 * resolved to a rectangle earlier. In this case, we will
		 * have a dest, and the shape will be unchanged.
		 */
		if (mask)
		{
			assert(dest);

#ifdef DUMP_GROUP_BLENDS
			dump_spaces(dev->top, "");
			fz_dump_blend(dev->dest, "Clipping ");
			if (dev->shape)
				fz_dump_blend(dev->shape, "/");
			fz_dump_blend(dest, " onto ");
			if (shape)
				fz_dump_blend(shape, "/");
			fz_dump_blend(mask, " with ");
#endif
			fz_paint_pixmap_with_mask(dest, dev->dest, mask);
			if (shape != NULL)
			{
				assert(shape != dev->shape);
				fz_paint_pixmap_with_mask(shape, dev->shape, mask);
				fz_drop_pixmap(ctx, dev->shape);
				dev->shape = shape;
			}
			fz_drop_pixmap(ctx, mask);
			fz_drop_pixmap(ctx, dev->dest);
			dev->dest = dest;
#ifdef DUMP_GROUP_BLENDS
			fz_dump_blend(dev->dest, " to get ");
			if (dev->shape)
				fz_dump_blend(dev->shape, "/");
			printf("\n");
#endif
		}
		else
		{
#ifdef DUMP_GROUP_BLENDS
			dump_spaces(dev->top, "Clip End\n");
#endif
			assert(dest == NULL);
			assert(shape == dev->shape);
		}
	}
}
Beispiel #2
0
static void fz_knockout_end(fz_context *ctx, void *user)
{
	fz_draw_device *dev = user;
	fz_pixmap *group = dev->dest;
	fz_pixmap *shape = dev->shape;
	int blendmode;
	int isolated;

	if ((dev->blendmode & FZ_BLEND_KNOCKOUT) == 0)
		return;

	if (dev->top == dev->stack_max)
		fz_grow_stack(dev);

	if (dev->top > 0)
	{
		dev->top--;
		blendmode = dev->blendmode & FZ_BLEND_MODEMASK;
		isolated = dev->blendmode & FZ_BLEND_ISOLATED;
		dev->blendmode = dev->stack[dev->top].blendmode;
		dev->shape = dev->stack[dev->top].shape;
		dev->dest = dev->stack[dev->top].dest;
		dev->scissor = dev->stack[dev->top].scissor;

#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top, "");
		fz_dump_blend(group, "Blending ");
		if (shape)
			fz_dump_blend(shape, "/");
		fz_dump_blend(dev->dest, " onto ");
		if (dev->shape)
			fz_dump_blend(dev->shape, "/");
		if (blendmode != 0)
			printf(" (blend %d)", blendmode);
		if (isolated != 0)
			printf(" (isolated)");
		printf(" (knockout)");
#endif
		if ((blendmode == 0) && (shape == NULL))
			fz_paint_pixmap(dev->dest, group, 255);
		else
			fz_blend_pixmap(dev->dest, group, 255, blendmode, isolated, shape);

		fz_drop_pixmap(ctx, group);
		if (shape != dev->shape)
		{
			if (dev->shape)
			{
				fz_paint_pixmap(dev->shape, shape, 255);
			}
			fz_drop_pixmap(ctx, shape);
		}
#ifdef DUMP_GROUP_BLENDS
		fz_dump_blend(dev->dest, " to get ");
		if (dev->shape)
			fz_dump_blend(dev->shape, "/");
		printf("\n");
#endif
	}
}
Beispiel #3
0
static void
fz_draw_end_group(fz_device *devp)
{
	fz_draw_device *dev = devp->user;
	int blendmode;
	int isolated;
	float alpha;
	fz_context *ctx = dev->ctx;
	fz_draw_state *state;

	if (dev->top == 0)
	{
		fz_warn(ctx, "Unexpected end_group");
		return;
	}

	state = &dev->stack[--dev->top];
	alpha = state[1].alpha;
	blendmode = state[1].blendmode & FZ_BLEND_MODEMASK;
	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 ");
	if (state[1].shape)
		fz_dump_blend(dev->ctx, state[1].shape, "/");
	fz_dump_blend(dev->ctx, state[0].dest, " onto ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	if (alpha != 1.0f)
		printf(" (alpha %g)", alpha);
	if (blendmode != 0)
		printf(" (blend %d)", blendmode);
	if (isolated != 0)
		printf(" (isolated)");
	if (state[1].blendmode & FZ_BLEND_KNOCKOUT)
		printf(" (knockout)");
#endif
	if ((blendmode == 0) && (state[0].shape == state[1].shape))
		fz_paint_pixmap(state[0].dest, state[1].dest, alpha * 255);
	else
		fz_blend_pixmap(state[0].dest, state[1].dest, alpha * 255, blendmode, isolated, state[1].shape);

	fz_drop_pixmap(dev->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);
	}
#ifdef DUMP_GROUP_BLENDS
	fz_dump_blend(dev->ctx, state[0].dest, " to get ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	printf("\n");
#endif

	if (state[0].blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(dev);
}
Beispiel #4
0
static void
fz_draw_pop_clip(fz_device *devp)
{
	fz_draw_device *dev = devp->user;
	fz_context *ctx = dev->ctx;
	fz_draw_state *state;

	if (dev->top == 0)
	{
		fz_warn(ctx, "Unexpected pop clip");
		return;
	}
	state = &dev->stack[--dev->top];

	/* We can get here with state[1].mask == NULL if the clipping actually
	 * resolved to a rectangle earlier.
	 */
	if (state[1].mask)
	{
#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top, "");
		fz_dump_blend(dev->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 ");
		if (state[0].shape)
			fz_dump_blend(dev->ctx, state[0].shape, "/");
		fz_dump_blend(dev->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(dev->ctx, state[1].mask);
		fz_drop_pixmap(dev->ctx, state[1].dest);
#ifdef DUMP_GROUP_BLENDS
		fz_dump_blend(dev->ctx, state[0].dest, " to get ");
		if (state[0].shape)
			fz_dump_blend(dev->ctx, state[0].shape, "/");
		printf("\n");
#endif
	}
	else
	{
#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top, "Clip end\n");
#endif
	}
}
Beispiel #5
0
static void fz_knockout_end(fz_draw_device *dev)
{
	fz_draw_state *state;
	int blendmode;
	int isolated;
	fz_context *ctx = dev->ctx;

	if (dev->top == 0)
	{
		fz_warn(ctx, "unexpected knockout end");
		return;
	}
	state = &dev->stack[--dev->top];
	if ((state[0].blendmode & FZ_BLEND_KNOCKOUT) == 0)
		return;

	blendmode = state->blendmode & FZ_BLEND_MODEMASK;
	isolated = state->blendmode & FZ_BLEND_ISOLATED;

#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top, "");
	fz_dump_blend(dev->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 ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	if (blendmode != 0)
		printf(" (blend %d)", blendmode);
	if (isolated != 0)
		printf(" (isolated)");
	printf(" (knockout)");
#endif
	if ((blendmode == 0) && (state[0].shape == state[1].shape))
		fz_paint_pixmap(state[0].dest, state[1].dest, 255);
	else
		fz_blend_pixmap(state[0].dest, state[1].dest, 255, blendmode, isolated, state[1].shape);

	fz_drop_pixmap(dev->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);
	}
#ifdef DUMP_GROUP_BLENDS
	fz_dump_blend(dev->ctx, state[0].dest, " to get ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	printf("\n");
#endif
}
Beispiel #6
0
static void
fz_draw_end_tile(fz_device *devp)
{
	fz_draw_device *dev = devp->user;
	float xstep, ystep;
	fz_matrix ctm, ttm, shapectm;
	fz_rect area;
	int x0, y0, x1, y1, x, y;
	fz_context *ctx = dev->ctx;
	fz_draw_state *state;

	if (dev->top == 0)
	{
		fz_warn(ctx, "Unexpected end_tile");
		return;
	}

	state = &dev->stack[--dev->top];
	xstep = state[1].xstep;
	ystep = state[1].ystep;
	area = state[1].area;
	ctm = state[1].ctm;

	x0 = floorf(area.x0 / xstep);
	y0 = floorf(area.y0 / ystep);
	x1 = ceilf(area.x1 / xstep);
	y1 = ceilf(area.y1 / ystep);

	ctm.e = state[1].dest->x;
	ctm.f = state[1].dest->y;
	if (state[1].shape)
	{
		shapectm = ctm;
		shapectm.e = state[1].shape->x;
		shapectm.f = state[1].shape->y;
	}

#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top, "");
	fz_dump_blend(dev->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 ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
#endif

	for (y = y0; y < y1; y++)
	{
		for (x = x0; x < x1; x++)
		{
			ttm = fz_concat(fz_translate(x * xstep, y * ystep), ctm);
			state[1].dest->x = ttm.e;
			state[1].dest->y = ttm.f;
			fz_paint_pixmap_with_rect(state[0].dest, state[1].dest, 255, state[0].scissor);
			if (state[1].shape)
			{
				ttm = fz_concat(fz_translate(x * xstep, y * ystep), shapectm);
				state[1].shape->x = ttm.e;
				state[1].shape->y = ttm.f;
				fz_paint_pixmap_with_rect(state[0].shape, state[1].shape, 255, state[0].scissor);
			}
		}
	}

	fz_drop_pixmap(dev->ctx, state[1].dest);
	fz_drop_pixmap(dev->ctx, state[1].shape);
#ifdef DUMP_GROUP_BLENDS
	fz_dump_blend(dev->ctx, state[0].dest, " to get ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	printf("\n");
#endif

	if (state->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(dev);
}